Intereting Posts
Установить видимость индикатора выполнения после завершения загрузки изображения с использованием библиотеки Glide Как сохранить изображение в базе данных SQLite Получить UID Linux для Android-приложения Crash: java.lang.NoClassDefFoundError: android.support.v7.appcompat.R $ layout SetURLStreamHandlerFactory и "java.lang.Error: Factory уже установлен" Как использовать библиотеку поддержки предпочтений v7 / v14? Android запускает музыкальный плеер, используя намерение ImageButton не выделяет клик с помощью Прозрачного фона Как применить слайд-анимацию между двумя действиями в Android? Как добавить кнопку на экран предпочтения? Отправка текстовых сообщений программно в android Как избежать мягкой клавиатуры, подталкивающей мой макет? Проблема относительного размещения Android с гравитацией Исключение «Ресурс не найден» при попытке загрузить ресурс в программе примера NotepadV1 Где файл данных приложения фактически хранится на устройстве Android?

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

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

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