Как получить абсолютные координаты вида



я пытаюсь получить абсолютные координаты пикселя экрана в верхнем левом углу вида. Однако, все методы, которые я могу найти, такие как getLeft() и getRight() не работают, как они все, кажется, относительно родителя зрения, тем самым давая мне 0. Как правильно это сделать?



если это поможет, это для "положить картину обратно в порядок" игры. Я хочу, чтобы пользователь мог нарисовать поле для выбора нескольких частей. Я предполагаю, что самый простой способ сделать это к getRawX() и getRawY() С MotionEvent а затем сравните эти значения с верхним левым углом макета, содержащего части. Зная размер кусков, я могу определить, сколько штук было выбрано. Я понимаю, что могу использовать getX() и getY() на MotionEvent, но как это возвращает относительное положение, что делает определение, какие части были выбраны более трудным. (Не невозможно, я знаю, но это кажется излишне сложным).



редактировать: этот код я используется, чтобы попытаться получить размер контейнера для хранения, согласно одному из вопросов. TableLayout - это таблица, которая содержит все части головоломки.



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


Edit 2: Вот код, который я пробовал, следуя более предлагаемым ответам.



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]);


этот код был добавлен после завершения инициализации. Изображение было разделено на массив изображений (массив ячеек []), содержащихся в пределах TableLayout. Ячейки[0] - это верхний левый ImageView, и я выбрал ячейки[4] как это где-то посередине и наиболее определенно не должны иметь координаты (0,0).



код, показанный выше, все еще дает мне все 0 в журналах, которые я действительно не понимаю, потому что правильно отображаются различные кусочки головоломки. (Я попробовал public int для tableLayoutCorners и видимости по умолчанию, оба дают тот же результат.)



я не знаю, если это важно, но ImageViews первоначально не задается размер. Размер ImageViews определяется во время инициализации автоматически видом, когда я даю ему изображение для отображения. Может ли это способствовать тому, что их значения равны 0, даже если этот код регистрации находится после того, как они получили изображение и автоматически изменили размер? Потенциально противостоять этому, я добавил код tableLayout.requestLayout() как показано выше, но это не помогло.

463   7  

7 ответов:

использовать View.getLocationOnScreen() и/или getLocationInWindow().

принятый ответ на самом деле не сказал, как получить местоположение, так что вот немного больше деталей. Вы проходите в int массив длины 2 и значения заменяются координатами вида (x, y) (верхнего, левого угла).

int[] location = new int[2];
myView.getLocationOnScreen(location);
int x = location[0];
int y = location[1];

Примечания

  • замена getLocationOnScreen С getLocationInWindow должны давать одинаковые результаты в большинстве случаев (см. ответ). Однако, если вы находитесь в меньшее окно, как диалоговое окно или пользовательская клавиатура, а затем использовать вам нужно будет выбрать, какой из них лучше соответствует вашим потребностям.
  • вы получаете (0,0) если вы вызываете этот метод в onCreate потому что вид еще не был выложен. Вы можете использовать ViewTreeObserver чтобы слушать, когда макет будет сделан, и вы можете получить измеренные координаты. (См.ответ.)

сначала вы должны получить localVisible прямоугольник вида

например:

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));

надеюсь, это поможет

использование слушателя глобального макета всегда хорошо работало для меня. Он имеет то преимущество, что может перемерять вещи, если макет изменен, например, если что-то настроено на просмотр.Исчезнувшие или дочерние представления добавляются / удаляются.

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);
 }

после комментария Ромена Гая, вот как я это исправил. Надеюсь, это поможет всем, кто также имел эту проблему.

Я действительно пытался получить позиции взглядов, прежде чем они были выложены на экране, но это было совсем не очевидно, что происходит. Эти строки были помещены после запуска кода инициализации, поэтому я предположил, что все готово. Однако этот код все еще находился в onCreate(); экспериментируя с потоком.sleep () я обнаружил, что макет фактически не завершена до тех пор, пока onCreate() полностью не завершит выполнение onResume (). Таким образом, действительно, код пытался запустить до того, как макет закончил позиционироваться на экране. При добавлении кода в OnClickListener (или какой-либо другой прослушиватель) были получены правильные значения, поскольку его можно было запустить только после завершения макета.


строка ниже была предложена в качестве редактирования сообщества:

пожалуйста, используйте onWindowfocuschanged(boolean hasFocus)

моя функция utils для получения местоположения просмотра, она вернет Point объект x value и y value

public static Point getLocationOnScreen(View view){
    int[] location = new int[2];
    view.getLocationOnScreen(location);
    return new Point(location[0], location[1]);
}

используя

Point viewALocation = getLocationOnScreen(viewA);

используйте этот код, чтобы найти точные X и y координирует :

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);

Я добавил / вычитал некоторые значения, чтобы настроить мой вид. пожалуйста, эти строки только после того, как весь вид был надут.

Comments

    Ничего не найдено.