0

I created a simple example to know how can I get the coordinates of any given view. Below are my attempts, and they always display 0.0. any idea why that happens?

Code:

private int [] tv1Location = new int[2];
private int [] tv2Location = new int[2];

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Rect tv1Rect = new Rect();
    Rect tv2Rect = new Rect();

    TableLayout tl = (TableLayout) findViewById(R.id.tableLayout);
    TextView tv1 = (TextView) findViewById(R.id.tv1);
    TextView tv2 = (TextView) findViewById(R.id.tv2);

    tv1.getLocalVisibleRect(tv1Rect);
    tv1.getLocationOnScreen(tv1Location);

    tv2.getLocalVisibleRect(tv1Rect);
    tv2.getLocationOnScreen(tv2Location);


    tv1.setText("xCords: "+tv1.getX()+", yCords: "+tv1.getY());
    tv2.setText("xCords: "+tv2.getX()+", yCords: "+tv2.getY());
    //tv2.setText("xCords: "+tv2Location[0]+", yCords: "+tv2Location[1]);
    //tv1.setText("xCords: "+tv1Location[0]+", yCords: "+tv1Location[1]);
    //tv2.setText("xCords: "+tv2Location[0]+", yCords: "+tv2Location[1]);

Updated

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    // TODO Auto-generated method stub
    super.onWindowFocusChanged(hasFocus);

    if (hasFocus) {
            tv1.getLocalVisibleRect(tv1Rect);
            tv1.getLocationOnScreen(tv1Location);

            tv2.getLocalVisibleRect(tv1Rect);
            tv2.getLocationOnScreen(tv2Location);

            //tv1.setText("xCords: "+tv1.getX()+", yCords: "+tv1.getY());
            //tv2.setText("xCords: "+tv2.getX()+", yCords: "+tv2.getY());
            //tv1.setText("xCords: "+tv1Rect.centerX()+", yCords: "+tv1Rect.centerY());
            //tv2.setText("xCords: "+tv2Rect.centerX()+", yCords: "+tv2Rect.centerY());
            //tv1.setText("xCords: "+tv1Location[0]+", yCords: "+tv1Location[1]);
            //tv2.setText("xCords: "+tv2Location[0]+", yCords: "+tv2Location[1]);
        }
    }
Amrmsmb
  • 1
  • 27
  • 104
  • 226
  • 3
    Put it in onStart instead of onCreate. The view isn't drawn yet in onCreate (or at least not guaranteed to be). – zgc7009 May 29 '14 at 18:12
  • @zgc7009 unfortunately, the coordinates still zero. please have a look at the update – Amrmsmb May 29 '14 at 18:21

3 Answers3

5

You Views are not visible yet. You shouldn't put code to check things like this in onCreate() because everything might not be drawn yet. There are several different ways to accomplish this. The best place may be in onWindowFocusChanged

The docs say onWindowFocusChanged()

This is the best indicator of whether this activity is visible to the user

So you know that the Views are laid out at this point. You could also post a runnable on the Views or use.

Here is an answer that uses the listener onGlobalLayout which could also work for what you need.

Community
  • 1
  • 1
codeMagic
  • 44,549
  • 13
  • 77
  • 93
3

Views are neither measured nor laid out at this point so instead do it like this:

textView.post(new Runnable() {
        @Override
        public void run() {
            textView.getLocalVisibleRect(rect);
            textView.setText("xCords: "+textView.getX()+", yCords: "+textView.getY());
        }
    });
M-Wajeeh
  • 17,204
  • 10
  • 66
  • 103
  • 1
    are you sure that onStart is called after the current run loop is finished? – Blackbelt May 29 '14 at 18:21
  • @M-WaJeEh please have a look at the updated answer. the commented out lines are giving me different coordinates, which ne should i use? – Amrmsmb May 29 '14 at 18:42
  • Thats because they are supposed to give different values. `X` is different from `centerX` of a `View`'s bounds. I thought it was obvious. – M-Wajeeh May 29 '14 at 18:48
0

A better way is to use the ViewTreeObserver, it will fire a callback when the layout is rendered which means you can get views' location.

tv1.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
   tv1.getLocalVisibleRect(tv1Rect);
});

In addition, you should remove the listener installed if you don't need it because the ViewTreeObserver holds a strong reference to your listener object.

Abhimanyu
  • 11,351
  • 7
  • 51
  • 121
bbsimon
  • 237
  • 2
  • 2