Определение порядка Z просмотров RelativeLayout в Android

195

Я хотел бы определить порядок z представлений RelativeLayout в Android.

Я знаю, что один из способов сделать это - это вызов bringToFront.

Есть ли лучший способ сделать это? Было бы здорово, если бы я мог определить порядок z в макете xml.

  • 4
    View.bringToFront (); это ансер
Теги:
relativelayout
android-relativelayout
z-order

12 ответов

277
Лучший ответ

Самый простой способ - просто обратить внимание на порядок, в котором Представления добавлены в ваш XML файл. Ниже в файле означает, что выше по оси Z.

Изменить: Здесь описано здесь и здесь на сайте разработчика Android. (Спасибо @flightplanner)

  • 0
    Хм, я не уверен. Я покопаюсь позже, чтобы посмотреть, что я смогу найти. Однако тот же принцип используется в другом месте; Полотна (используются для 2D-графики) работают так же. Поэтому я подозреваю, что это не изменится. Тем не менее, это хорошая вещь, чтобы проверить.
  • 15
    К сожалению, это не всегда возможно изменить. Например, в относительной компоновке каждый элемент может быть размещен только по отношению к ранее определенным в файле
Показать ещё 10 комментариев
84

Если вы хотите сделать это в коде вы можете сделать

View.bringToFront();

см. docs

52

Обратите внимание: кнопки и другие элементы в API 21 и выше имеют высокую высоту и, следовательно, игнорируют порядок элементов xml независимо от родительского макета. Принял меня немного, чтобы понять, что один из них.

  • 11
    Решением этой ошибки для меня было вызвать setElevation (1000) для представления, которое я хочу визуализировать через кнопку.
13

Я столкнулся с теми же проблемами: в относительном макете parentView у меня есть 2 дочерних элемента childView1 и childView2. Сначала я помещаю childView1 выше childView2, и я хочу, чтобы childView1 находился поверх childView2. Изменение порядка взглядов детей не решило проблему для меня. Что для меня работало, это установить android: clipChildren = "false" в parentView и в коде, который я установил:

childView1.bringToFront();

parentView.invalidate();
  • 2
    Это работает, и Android делает меня так грустно. child.bringToFront() с parent.invalidate() работает, а parent.bringChildToFront(child) - нет. Где логика, которую мы все ожидаем от ОС?
  • 2
    В LinearLayout порядок детей ...
12

В Android, начиная с уровня API 21, элементы в файле макета получают их порядок Z как от того, как они упорядочены в файле, как описано в правильном ответе, так и с их высоты, более высокое значение высоты означает, что элемент получает более высокий порядок Z.

Это может иногда вызвать проблемы, особенно с кнопками, которые часто появляются поверх элементов, которые в соответствии с порядком XML должны быть ниже их в порядке Z. Чтобы исправить это, просто установите android:elevation элементов в XML вашего макета в соответствии с порядком Z, который вы хотите достичь.

Я установил высоту элемента в макете, и он начнет бросать тень. Если вы не хотите этого эффекта, вы можете удалить тень с помощью кода следующим образом:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
   myView.setOutlineProvider(null);
}

Я не нашел способа удалить тень повышенного вида через макет xml.

12

Обратите внимание, что вы можете использовать view.setZ(float), начиная с уровня API 21. Здесь вы можете найти дополнительную информацию.

11

Думаю, я бы добавил ответ с момента появления

андроида: translationZ

Поле XML изменило ситуацию немного. Другие ответы, предлагающие запуск

childView1.bringToFront();

parentView.invalidate();

являются полностью пятнами на EXCEPT, потому что этот код НЕ приведет childView1 перед любым представлением с жестко запрограммированным андроидом: translationZ в файле XML. У меня возникли проблемы с этим, и, как только я удалил это поле из других представлений, метод bringToFront() работал нормально.

  • 0
    это также верно для elevation Android 5
4

API 21 имеет view.setElevation(float)

Использовать ViewCompat.setElevation(view, float); для обратной совместимости

Дополнительные методы ViewCompat.setZ(v, pixels) и ViewCompat.setTranslationZ(v, pixels)

Другой способ собрать кнопки или просмотреть массив и использовать addView для добавления в RelativeLayout

3

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

lastView.setTranslationZ(-10);

см. https://developer.android.com/reference/android/view/View.html#setTranslationZ(float) для более

  • 0
    Спасибо, работает только для API 21 и выше.
1

Вы можете использовать пользовательский RelativeLayout с переопределенным

protected int getChildDrawingOrder (int childCount, int i)

Знайте - этот метод принимает param i как "какое представление следует рисовать i'th". Вот как работает ViewPager. Он устанавливает пользовательский порядок рисования в сочетании с PageTransformer.

0

Или поместите перекрывающуюся кнопку или представления внутри FrameLayout. Затем RelativeLayout в xml файле будет учитывать порядок дочерних макетов при их добавлении.

0

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню