I would like to define the z order of the views of a RelativeLayout in Android.
I know one way of doing this is calling bringToFront
.
Is there are better way of doing this? It would be great if I could define the z order in the layout xml.
In Android starting from API level 21, items in the layout file get their Z order both from how they are ordered within the file, as described in correct answer, and from their elevation, a higher elevation value means the item gets a higher Z order.
This can sometimes cause problems, especially with buttons that often appear on top of items that according to the order of the XML should be below them in Z order. To fix this just set the android:elevation
of the the items in your layout XML to match the Z order you want to achieve.
I you set an elevation of an element in the layout it will start to cast a shadow. If you don't want this effect you can remove the shadow with code like so:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
myView.setOutlineProvider(null);
}
I haven't found any way to remove the shadow of a elevated view through the layout xml.
Please note that you can use view.setZ(float)
starting from API level 21. Here you can find more info.
I encountered the same issues: In a relative layout parentView, I have 2 children childView1 and childView2. At first, I put childView1 above childView2 and I want childView1 to be on top of childView2. Changing the order of children views did not solve the problem for me. What worked for me is to set android:clipChildren="false" on parentView and in the code I set:
childView1.bringToFront();
parentView.invalidate();
Thought I'd add an answer since the introduction of the
android:translationZ
XML field changed things a tad. The other answers that suggest running
childView1.bringToFront();
parentView.invalidate();
are totally spot on EXCEPT for that this code will NOT bring childView1 in front of any view with a hardcoded android:translationZ in the XML file. I was having problems with this, and once I removed this field from the other views, bringToFront() worked just fine.
childView.bringToFront() didn't work for me, so I set the Z translation of the least recently added item (the one that was overlaying all other children) to a negative value like so:
lastView.setTranslationZ(-10);
see https://developer.android.com/reference/android/view/View.html#setTranslationZ(float) for more
You can use custom RelativeLayout
with redefined
protected int getChildDrawingOrder (int childCount, int i)
Be aware - this method takes param i
as "which view should I draw i'th
".
This is how ViewPager
works. It sets custom drawing order in conjuction with PageTransformer
.