Question

I have to add an ImageView programatically to an RelativeLayout such that it's 100dp to right of the center. I did this for a specific screen size and resolution, but I want it to work on any size of phone and desnity. What I tried for this is as follows :

CODE :

    float xCord, yCord;
    float xCenter, yCenter;
    float radius;
    float angle;
    double x, y;

    TextView tv;
    RelativeLayout container;
    ImageView view;
    RelativeLayout.LayoutParams viewParams;
    DisplayMetrics metrics ;
    float density;
    int dps,pxs;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_circular_animation);

        metrics = getApplicationContext().getResources().getDisplayMetrics();
        float width = metrics.widthPixels;
        float height = metrics.heightPixels;



        tv = (TextView)findViewById(R.id.tv);
        container = (RelativeLayout)findViewById(R.id.container);

        xCenter = convertToDP(width)/2;
        yCenter = convertToDP(height)/2;
        radius = 100;
        angle = 0;

        x = xCenter + radius * Math.cos(angle * Math.PI / 180);
        y = yCenter + radius * Math.sin(angle * Math.PI / 180);

        view = new ImageView(this);
        viewParams = new RelativeLayout.LayoutParams(50,50);
        viewParams.leftMargin = (int) x;
        viewParams.topMargin = (int) y;
        view.setLayoutParams(viewParams);
        view.setImageResource(R.drawable.square);
        container.addView(view);

        tv.setText(String.valueOf(xCenter) + " " + String.valueOf(yCenter));
    }

    public int convertToDP(float px) {

        density = getApplicationContext().getResources().getDisplayMetrics().density;       
        dps = (int) ((px/density) + 0.5f);
        return dps;
    }

}

What I did is like, get the screen size and density and then divide it by 2 to get the center cords. Once i had the cords I used the formula to get the point on circumference of the circle at 0deg, but I am not getting the correct point. Any help would be great.

Was it helpful?

Solution

Try this:

public class sampleMediaPlayer extends Activity {
    // Toast mToast;
    // int i = 0;
    // private boolean click;
    // private Camera camera;
    Handler mHandler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mainf);

    }

    @Override
    protected void onResume() {

        mHandler.postDelayed(new Runnable() {

            @Override
            public void run() {
                RelativeLayout rl = (RelativeLayout) findViewById(R.id.relativeLayout);

                float r = DPtoPX(100);
                float mScreenWidth = rl.getWidth() / 2; // DPtoPX(100);
                float mScreenHeight = rl.getHeight() / 2;// DPtoPX(100);

                for (int i = 0; i < 360; i = i + 30) {
                    addView(rl, (int) (mScreenWidth + r * Math.cos(i * Math.PI / 180F)),
                            (int) (mScreenHeight + (int) r * Math.sin(i * Math.PI / 180F)));

                }

                addView(rl, (int) mScreenWidth, (int) ((mScreenHeight)));

            }
        }, 50);

        super.onResume();
    }

    void addView(ViewGroup rl, int x, int y) {
        Log.i("NIMISH", x + " = " + y);
        ImageView CenterImage = new ImageView(this);
        RelativeLayout.LayoutParams viewParamsCenter = new RelativeLayout.LayoutParams(10, 10);
        // viewParamsCenter.addRule(RelativeLayout.CENTER_IN_PARENT);
        viewParamsCenter.leftMargin = x;
        viewParamsCenter.topMargin = y;
        CenterImage.setLayoutParams(viewParamsCenter);
        CenterImage.setImageResource(R.drawable.ic_launcher);

        rl.addView(CenterImage);
    }

    float DPtoPX(float dp) {
        Resources r = getResources();
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());
    }
}

Explanation:

   float width = metrics.widthPixels;
   float height = metrics.heightPixels;

Returns the screen size including the TitleBar and StatusBar, but when you plot the image it calculated relative to that of the RelativeLayout. So if you draw image with height 'metrics.heightPixels' you will observe image to be out of screen. This phenomenon affects calculation of true center.

there are some other ways to calculate but each require that view to be plotted on screen. Hence any call after onResume()( used handler). As you can observe the function of calculating titlebar heights returns 0 when called form onResume().

private float Correction() {
    Rect rectgle = new Rect();
    Window window = getWindow();
    window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
    int StatusBarHeight = rectgle.top;
    int contentViewTop = window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
    int TitleBarHeight = contentViewTop - StatusBarHeight;

    Log.i("NIMISH", "StatusBar Height= " + StatusBarHeight + " , TitleBar Height = " + TitleBarHeight);
    return contentViewTop;
}

If you want user to input the X,Y coordinated you can alter the first program by

 float mScreenWidth   = DPtoPX(100);
 float mScreenHeight  = DPtoPX(100);

Doing so, It will plot the image with reference to the Relative layout, So you can remove the handler.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top