Intereting Posts
Как обнаружить Android-планшеты в целом. UserAgent? Получить координаты центра веб-страницы на планшетных устройствах с использованием JavaScript Сохранение пользовательского интерфейса при изменении ориентации – onSaveInstanceState не работает, как ожидалось, если сохранить фрагмент Очень большой ответ SOAP – ошибка в Android-памяти Профайл proguard.cfg отсутствует Appcompatv7 – v21 Ящик для навигации, не показывающий значок гамбургера Если я объявляю фрагмент в XML-макете, как передать его Bundle? Самый эффективный способ рисования нескольких одинаковых объектов? Для чего используется ids.xml? Стрелка вверх не отображается после вызова ActionBarDrawerToggle.setDrawerIndicatorEnabled (false) Android TextView не выбирается в CoordinatorLayout? (TextView не поддерживает выбор текста. Отменен выбор) Android Добавить изображение в текст (в текстовом режиме)? В чем разница между макетом и контейнером в Android? FragmentManager заменить vs Добавить Как получить все имена таблиц в базе данных android sqlite?

GetLocationOnScreen () vs getLocationInWindow ()

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

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

Думаю, этого было бы достаточно:

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

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

getLocationOnScreen() или getLocationInWindow() ?

(Добавив, конечно, половину ширины кнопки)

Solutions Collecting From Web of "GetLocationOnScreen () vs getLocationInWindow ()"

Примечание – этот ответ не был принятым ответом, когда он был написан, поэтому он сформулирован как опровержение другого ответа

Я не думаю, что принятый ответ правильный. Если я создаю новый проект и отредактирую только 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.

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

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

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

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

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


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

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

GetLocationInWindow () получит местоположение на основе окна активности .

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

| – Охота и рыбалка
| ——– Состояние бара ——————— |
| |
| ——————————————- |
| ——– Окно активности —— ——- |
| |
| |
| |
| |
| |
| |
| ——————————————- |

Для координаты x значение обоих методов обычно одинаково.

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