Как я могу динамически установить позицию представления в Android?

Как я могу изменить положение просмотра через код? Как изменение его позиции X, Y. Возможно ли это?

Ответ 1

Для чего-либо ниже Honeycomb (API Level 11) вам нужно будет использовать setLayoutParams(...).

Если вы можете ограничить поддержку Honeycomb и вверх, вы можете использовать setX(...), setY(...), setLeft(...), setTop(...) и т.д.

Ответ 2

Да, вы можете динамически установить позицию просмотра в Android. Аналогично, у вас есть ImageView в LinearLayout вашего xml файла. Таким образом, вы можете установить его позицию через LayoutParams. Но не забудьте взять LayoutParams в соответствии с макетом, сделанным в вашем xml файле. Существуют разные LayoutParams в соответствии с принятым макетом.

Вот код для установки:

    LayoutParams layoutParams=new LayoutParams(int width, int height);
    layoutParams.setMargins(int left, int top, int right, int bottom);
    imageView.setLayoutParams(layoutParams);

Надеюсь, вам будет полезно установить положение.

Ответ 3

Уже существуют разные действительные ответы, но ни один из них не предлагает правильного указания того, какой метод использовать в этом случае, за исключением соответствующих ограничений уровня API:

  • Если вы можете дождаться цикла компоновки, а группа родительского представления поддерживает MarginLayoutParams (или подкласс), установите marginLeft/marginTop соответственно.

  • Если вам нужно немедленно и постоянно менять позицию (например, для якоря PopupMenu), дополнительно вызывайте layout(l, t, r, b) с теми же координатами. Это упреждает, что система макета подтвердит позже.

  • Для немедленных (временных) изменений (например, анимации) используйте setX()/setY(). В случаях, когда размер родителя не зависит от WRAP_CHILDREN, может быть очень просто использовать setX()/setY().

  • Никогда использовать setLeft()/setRight()/setBottom()/setTop(), см. ниже.

Фон: Поля mLeft/mTop/mBottom/mRight заполняются из соответствующих LayoutParams в макете(). Макет называется неявно и асинхронно системой отображения вида Android. Таким образом, установка MarginLayoutParams представляется самым безопасным и самым чистым способом установки позиции на постоянной основе. Однако асинхронное отставание макета может быть проблемой в некоторых случаях, например. при использовании представления для визуализации курсора, и он должен быть перепозиционирован и одновременно служить якорем PopupMenu. В этом случае вызов layout() работал отлично для меня.

Проблемы с setLeft() и setTop() следующие:

  • Вызов одного из них недостаточен - вам также нужно вызвать setRight() и setBottom(), чтобы избежать растягивания или сжатия представления.

  • Реализация этих методов выглядит относительно сложной (= выполнение некоторой работы для учета изменений размера представления, вызванных каждым из них)

  • Они, похоже, вызывают странные проблемы с полями ввода: мягкая цифровая клавиатура EditText иногда не позволяет цифры

setX() и setY() работают вне системы компоновки, а соответствующие значения рассматриваются как дополнительное смещение к значениям left/top/bottom/right, определяемым системой компоновки, соответственно изменяя представление. Кажется, что они добавлены для анимаций (где требуется немедленный эффект без прохождения цикла компоновки).

Ответ 4

Существует библиотека под названием NineOldAndroids, которая позволяет использовать библиотеку анимации Honeycomb вплоть до версии 1.

Это означает, что вы можете определить left, right, translationX/Y с немного другим интерфейсом.

Вот как это работает:

ViewHelper.setTranslationX(view, 50f);

Вы просто используете статические методы из класса ViewHelper, передаете представление и какое значение всегда хотите установить.

Ответ 5

Я бы рекомендовал использовать setTranslationX и setTranslationY. Я только начинаю заниматься этим, но они кажутся самым безопасным и предпочтительным способом перемещения взгляда. Я думаю, это зависит от того, что именно вы пытаетесь сделать, но это хорошо работает для меня для 2D-анимации.

Ответ 6

Вы можете использовать следующие методы, если используете HoneyComb Sdk (API Level 11).

view.setX(float x);

Параметр x - это визуальная позиция x этого представления.

view.setY(float y);

Параметр y - это визуальная позиция этого представления.

Я надеюсь, что это будет полезно для вас.:)

Ответ 7

Для поддержки всех уровней API вы можете использовать это следующим образом:

ViewPropertyAnimator.animate(view).translationYBy(-yourY).translationXBy(-yourX).setDuration(0);

Ответ 8

Установите левую позицию этого представления относительно его родителя:

view.setLeft(int leftPosition);

Установите правильное положение этого представления относительно его родителя:

view.setRight(int rightPosition);

Установите верхнее положение этого представления относительно его родителя:

view.setTop(int topPosition);

Установите нижнюю позицию этого представления относительно своего родителя:

view.setBottom(int bottomPositon);

Вышеуказанные методы используются для установки позиции, связанной с ее родителем.

Ответ 9

Используйте LayoutParams. Если вы используете LinearLayout, вам нужно импортировать android.widget.LinearLayout.LayoutParams, иначе импортировать правильную версию LayoutParams для используемого вами макета, иначе это вызовет ClassCastException, а затем:

LayoutParams layoutParams = new LayoutParams(int width, int height);
layoutParams.setMargins(int left, int top, int right, int bottom);
imageView.setLayoutParams(layoutParams);

Примечание: обратите внимание, что вы также можете использовать imageView.setLeft(int dim), НО ЭТО НЕ БУДЕТ устанавливать позицию компонента, он будет устанавливать только позицию левой границы компонента, остальные останутся на та же позиция.

Ответ 10

Используйте RelativeLayout, поместите в него свое представление, получите RelativeLayout.LayoutParams объект из своего представления и задайте поля по мере необходимости. Затем вызовите requestLayout() на свой вид. Это единственный способ, который я знаю.

Ответ 11

Я обнаружил, что @Stefan Haustein очень близко подходит к моему опыту, но не уверен на 100%. Мое предложение:

  • setLeft()/setRight()/setBottom()/setTop() иногда не работают.
  • Если вы хотите временно установить позицию (например, для анимации, не затрагивающей иерархию), когда вид был добавлен и показан, просто используйте setX()/setY() вместо. (Возможно, вы захотите найти больше в разнице setLeft() и setX())
  • И обратите внимание, что X, Y кажутся абсолютными, и это было поддержано AbsoluteLayout, который сейчас устарел. Таким образом, вы чувствуете, что X, Y, скорее всего, больше не поддерживается. И да, но только частично. Это означает, что если ваш вид добавлен, setX(), setY() будут отлично работать; в противном случае , когда вы пытаетесь добавить представление в макет группы представлений (например, FrameLayout, LinearLayout, RelativeLayout), вы должны установить его LayoutParams с помощью marginLeft, marginTop вместо этого (setX(), setY() в этом случае иногда не будут работать).
  • Установка позиции представления с помощью marginLeft и marginTop является несинхронизированным процессом. Так что нужно немного времени, чтобы обновить иерархию. Если вы используете вид сразу после установки поля для него, вы можете получить неверное значение.

Ответ 12

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

Это позволяет добавить представление к последней позиции (или концу) в родительском представлении, выполнив что-то вроде этого:

int childCount = parent.getChildCount();
parentView.addView(newView, childCount);

В качестве альтернативы вы можете заменить представление следующим образом:

int childIndex = parentView.indexOfChild(childView);
childView.setVisibility(View.GONE);

parentView.addView(newView, childIndex);