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


226

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

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

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


4
View.bringToFront (); является Anser
Shirish Herwade

Ответы:


314

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

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


16
К сожалению, это не всегда возможно изменить. Например, в относительной компоновке каждый элемент может быть размещен только по отношению к тем, которые были ранее определены в файле
Casebash

67
Casebash, я не думаю, что в этом случае вам просто нужно использовать "@ + id / your_element_before_its_defined", а затем использовать тот же идентификатор в элементе, который вы определите позже. Я могу ошибаться, эти макеты очень сложны для меня, но у меня определенно складывается впечатление, что это работает.
tjb

7
TJB прав (и я рад, что он). Используйте @ + id с самым первым упоминанием идентификатора, например layout_above = "@ + id / some_id"
Michiel

3
Вы также можете поместить <item type = "id" name = "<your_id>" /> в XML-файл значений и затем ссылаться на него где угодно.
Карл

8
Я знаю, что опаздываю на вечеринку примерно на 3 года, но в ответ на @hpique это задокументировано здесь
HexAndBugs


68

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


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

setElevation () требует API уровня 21
dp2050

21

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

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

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

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

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


1
Как уже упоминалось в комментариях, вы можете использовать android:elevation="1000dp". Никакая тень не отображается таким образом.
Вадим Котов

15

Я столкнулся с теми же проблемами: в относительной компоновке 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)нет. Где логика, которую мы все ожидаем от ОС?
Оливер Хауслер

Чтобы анимировать некоторые виды (переводы в X и Y), я попробовал несколько комбинаций для LinearLayout, FrameLayout и RelativeLayout, но всегда были проблемы (связанные с перекрытиями или не пропорциональными размерами). Наконец-то android:clipChildren="false"сделал свое дело. Спасибо!
JCarlosR

15

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


13

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

андроид: translationZ

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

childView1.bringToFront();

parentView.invalidate();

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


это также верно для андроида 5elevation
shelll

5

API 21 имеет view.setElevation(float) встроенную

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

Больше методов ViewCompat.setZ(v, pixels)иViewCompat.setTranslationZ(v, pixels)

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


4

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

lastView.setTranslationZ(-10);

см. https://developer.android.com/reference/android/view/View.html#setTranslationZ(float) для получения дополнительной информации.


1

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

protected int getChildDrawingOrder (int childCount, int i)

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


0

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


0

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


0

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

ViewCompat.setElevation(sourceView, ViewCompat.getElevation(mCardView)+1);

Это обратно совместимо. Вот mCardViewвид, который должен быть ниже sourceView.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.