How to get the absolute coordinates of a view

Posted by Kulak on Sat, 15 Feb 2020 09:53:47 +0100

I am trying to get the absolute screen pixel coordinates in the upper left corner of the view. However, all the methods I can find, getLeft(), such as getLeft() and getRight(), don't work because they all seem to be relative to the view's parent, so give me 0. What's the right way?

If helpful, for the put pictures back in order game. I want users to be able to draw a box to select multiple clips. My assumption is that the easiest way to do this is to getRawX() and getRawY() from MotionEvent and then compare these values with the upper left corner of the layout holder. Knowing the size of the fragment, I can determine how many fragments I have selected. I know I can use getX() and getY() in MotionEvent, but as a return relative position, it's more difficult to determine which one is selected. I know it's not impossible, but it seems unnecessarily complicated.

Edit: according to one of the questions, this is the code I used to try to get the size of the save container. TableLayout is a table that contains all the puzzles.

TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
Log.d(LOG_TAG, "Values " + tableLayout.getTop() + tableLayout.getLeft());

Editor 2: This is the code I've tried, follow more suggested answers.

public int[] tableLayoutCorners = new int[2];
(...)

TableLayout tableLayout = (TableLayout) findViewById(R.id.tableLayout);
tableLayout.requestLayout();
Rect corners = new Rect();
tableLayout.getLocalVisibleRect(corners);
Log.d(LOG_TAG, "Top left " + corners.top + ", " + corners.left + ", " + corners.right
            + ", " + corners.bottom);

cells[4].getLocationOnScreen(tableLayoutCorners);
Log.d(LOG_TAG, "Values " + tableLayoutCorners[0] + ", " + tableLayoutCorners[1]);

This code is added when all initialization is complete. The image is divided into an ImageViews array (cells [] array) contained within TableLayout. Cells [0] is the upper left side of ImageView. I chose cells [4] because it is in the middle of the image, and it should never have coordinates of (0,0).

The code shown above still provides me with all zeros in the log. I really don't understand it, because each puzzle is displayed correctly. (I try to use public int to get tablelayoutcores and default visibility, and the results are the same.)

I don't know if this makes sense, but ImageView didn't initially give the size. When I display an image to ImageView, View automatically determines the size of the ImageView during initialization. Even if the logging code is after giving them an image and automatically resizing, will this cause them to have a value of 0? To solve this problem, I added the code tableLayout.requestLayout() as shown above, but it didn't help.

#1 building

Using the global layout listener has always worked for me. Its advantage is that if you change the layout (for example, if you set something to View.GONE or add / remove subviews), you can re measure the content.

public void onCreate(Bundle savedInstanceState)
{
     super.onCreate(savedInstanceState);

     // inflate your main layout here (use RelativeLayout or whatever your root ViewGroup type is
     LinearLayout mainLayout = (LinearLayout ) this.getLayoutInflater().inflate(R.layout.main, null); 

     // set a global layout listener which will be called when the layout pass is completed and the view is drawn
     mainLayout.getViewTreeObserver().addOnGlobalLayoutListener(
       new ViewTreeObserver.OnGlobalLayoutListener() {
          public void onGlobalLayout() {
               //Remove the listener before proceeding
               if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                    mainLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
               } else {
                    mainLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
               }

               // measure your views here
          }
       }
     );

     setContentView(mainLayout);
 }

#2 building

Use View.getLocationOnScreen() And / or getLocationInWindow() .

#3 building

First, you must get the localVisible rectangle of the view

For example:

Rect rectf = new Rect();

//For coordinates location relative to the parent
anyView.getLocalVisibleRect(rectf);

//For coordinates location relative to the screen/display
anyView.getGlobalVisibleRect(rectf);

Log.d("WIDTH        :", String.valueOf(rectf.width()));
Log.d("HEIGHT       :", String.valueOf(rectf.height()));
Log.d("left         :", String.valueOf(rectf.left));
Log.d("right        :", String.valueOf(rectf.right));
Log.d("top          :", String.valueOf(rectf.top));
Log.d("bottom       :", String.valueOf(rectf.bottom));

I hope it will help

#4 building

Following the comments of Romain Guy, that's how I deal with it. I hope it can help others who have this problem.

In fact, I'm trying to get the location of the view and then put it on the screen, but that's not the case. These lines are placed after the initialization code runs, so I think everything is ready. However, this code is still in onCreate(); by testing Thread.sleep(), I found that the layout was not really determined until all the execution from onCreate() to onResume(). So it's true that the code is trying to run before the layout is positioned on the screen. By adding code to OnClickListener (or some other listener), you can get the correct value because it can only be triggered after the layout is complete.

The following lines are recommended for community editing:

Please use onWindowfocuschanged(boolean hasFocus)

#5 building

Use this code to find the exact X and Y coordinates:

int[] array = new int[2];
ViewForWhichLocationIsToBeFound.getLocationOnScreen(array);
if (AppConstants.DEBUG)
    Log.d(AppConstants.TAG, "array  X = " + array[0] + ", Y = " + array[1]);
ViewWhichToBeMovedOnFoundLocation.setTranslationX(array[0] + 21);
ViewWhichToBeMovedOnFoundLocation.setTranslationY(array[1] - 165);

I added / subtracted some values to adjust my point of view. Perform these rows only after zooming in on the entire view.

Topics: Fragment