getLocationOnScreen () vs getLocationInWindow()


в чем разница между экраном и посмотреть в контексте этих двух методов?

у меня есть кнопка, и я хочу получить координату x ее центра.

Я думаю, этого будет достаточно:

public int getButtonXPosition() {
    return (button.getLeft()+button.getRight())/2;
}

но тогда, какая разница, если бы я использовал

getLocationOnScreen() или getLocationInWindow() ?

(добавляя половину ширины кнопки к этому, конечно)

3 58

3 ответа:

не думаю ответ является правильным. Если я создаю новый проект и редактирую только MainActivity, добавив следующий фрагмент:

public boolean dispatchTouchEvent(MotionEvent ev) {
    View contentsView = findViewById(android.R.id.content);

    int test1[] = new int[2];
    contentsView.getLocationInWindow(test1);

    int test2[] = new int[2];
    contentsView.getLocationOnScreen(test2);

    System.out.println(test1[1] + " " + test2[1]);

    return super.dispatchTouchEvent(ev);
}

Я увижу распечатку на консоли 108 108. Это использует Nexus 7 под управлением 4.3. У меня есть аналогичные результаты с помощью эмуляторов под управлением android версии еще 2.2.

нормальная активность windows будет иметь FILL_PARENTxFILL_PARENT в качестве своего WindowManager.LayoutParams, что приводит к тому, что они выкладывают размер всего экрана. Окно расположено под (в отношении z-порядка, а не y-координат) панелью состояния и другими украшениями, поэтому я считаю, что более точная диаграмма будет:

|--phone screen-----activity window---| 
|--------status bar-------------------| 
|                                     | 
|                                     | 
|-------------------------------------| 

если вы пройдете через источник этих двух методов, вы увидите, что getLocationInWindow пересекает иерархию представлений вашего представления до RootViewImpl, суммируя координаты представления и вычитание родительских смещений прокрутки. В случае, описанном выше, ViewRootImpl получает строку состояния высота от WindowSession и передача его вниз через fitSystemWindows к ActionBarOverlayLayout, который добавляет Это значение к высоте панели действий. Затем ActionBarOverlayLayout принимает это суммированное значение и применяет его к своему представлению содержимого, которое является родительским для вашего макета, в качестве поля.

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

если вы смотрите в getLocationOnScreen Источник вы увидите, что она просто называет getLocationInWindow а затем добавляет левый и верхний координаты окна (которые также передаются в представление ViewRootImpl, который извлекает их из WindowSession). В нормальном случае, эти значения будут равны нулю. Есть некоторые ситуации, когда эти значения могут быть ненулевыми, например диалоговое окно, которое находится в середине экрана.


Итак, подведем итог: A окно нормальной активности заполняет весь экран, даже пространство под строкой состояния и декорациями. Два рассматриваемых метода будут возвращать одни и те же координаты x и y. Только в особых случаях, таких как Диалоги, где окно фактически смещено, эти два значения будут отличаться.

getLocationOnScreen () получит местоположение на основе экран телефона.

getLocationInWindow () получит местоположение на основе окне действия.

на нормальную деятельность(не полноэкранная активность), связь с экраном телефона и окном активности, как показано ниже:

|--экран телефона--------------------- |
|--------статус бар---------------------|
| /
|-------------------------------------------|
|--------окне действия------ -------|
| /
| /
| /
| /
| /
| /
|-------------------------------------------|

X-координату, значение как метод, как правило, одинаковы.

для координаты y значения имеют разницу для высоты строки состояния

текущий принятый ответ немного многословен. Вот более короткий.

getLocationOnScreen() и getLocationInWindow() обычно возвращают те же значения. Это связано с тем, что окно обычно имеет тот же размер, что и экран. Однако иногда окно меньше, чем экран. Например, в Dialog или пользовательская системная клавиатура.

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

по теме