getLocationOnScreen () vs getLocationInWindow ()

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

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

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

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

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

getLocationOnScreen() или getLocationInWindow() ?

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

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

 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 затем берет это суммарное значение и применяет его к своему представлению содержимого, которое является родителем вашего макета, в качестве поля.

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

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


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

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

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

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

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

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

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

Текущий принятый ответ немного многословен. Здесь короче.

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

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

Связанный

  • Как получить координаты
  • Правильный способ добавления внешних банок (lib / *. Jar) в проект IntelliJ IDEA
  • Android-аудио FFT для получения определенной величины частоты с использованием аудиозаписей
  • Может ли Android SDK работать с JDK 1.7?
  • добавление текстового интерфейса для перетаскивания - Android / Java
  • Алгоритм наводнения в Android
  • Не удалось выполнить com.google.android.gms play-services-auth: 11.4.0
  • Как использовать интерфейс для связи между двумя действиями
  • Действительно ли невозможно защитить приложения Android от обратного проектирования?
  • Android - предотrotation перезагрузки WebView при повороте
  • Программно получать MAC-адрес устройства Android
  • Хостинг исполняемого файла в приложении Android
  • Давайте будем гением компьютера.