Intereting Posts
Публикация обновлений Android на рынок – как долго они появятся? Как автоматически определить необходимость iScroll? Предназначение для получения нескольких изображений Скопируйте файлы из папки SD-карты в другую папку на SD-карте Как получить черновик SMS в Android 6 Marshmallow ArrayList для массива строк в java ProGuard не скомпилировался с использованием Joda Time, используемого в Windows Программное обеспечение для Android NDK с собственным профилем кода на реальных телефонах Android Нарисуйте панель навигации (и другие приложения) в версии Android> = 5 Как подключить Android с MySQL с помощью драйвера Mysql JDBC Параллельные HTTP-запросы с доработкой Как добавить строку в нижней части счетчика, как, например, edittext в android Раздражающие лагами / заиканиями в игре для Android Где приложения Android вызывают SQLite getWritableDatabase? Android DDMS (Monitor) не запускается, если пользовательский профиль содержит пробел в нем

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

Я пытаюсь получить абсолютные координаты пикселя в верхнем левом углу представления. Тем не менее, все методы, которые я могу найти, такие как 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()); 

Редактирование 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]); 

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

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

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

Solutions Collecting From Web of "Как получить абсолютные координаты вида"

Используйте View.getLocationOnScreen() и / или getLocationInWindow() .

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

Например:

 Rect rectf = new Rect(); <imageView>or<view>.getLocalVisibleRect(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)); 

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

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

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

Принятый ответ на самом деле не сказал, как получить место, поэтому здесь немного подробнее. Вы передаете массив 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 этот метод в onCreate потому что представление еще не было выложено. Вы можете использовать ViewTreeObserver для прослушивания, когда макет сделан, и вы можете получить измеренные координаты. (См. Этот ответ .)

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

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


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

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

Используйте этот код, чтобы найти точные корды 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); 

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