How to bring view in front of everything?

AndroidAnimationButtonTextviewZ Order

Android Problem Overview


I have activity and a lot of widgets on it, some of them have animations and because of the animations some of the widgets are moving (translating) one over another. For example the text view is moving over some buttons . . .

Now the thing is I want the buttons to be always on the front. And when the textview is moving I want to move behind the buttons.

I can not achieve this I tried everything I know, and "bringToFront()" definitelly doesn't work.

note I do not want to control the z-order by the order of placing element to layout cause I simply can't :), the layout is complex and I can not place all the buttons at the begging of the layout

Android Solutions


Solution 1 - Android

You can call bringToFront() on the view you want to get in the front

This is an example:

    yourView.bringToFront();

Solution 2 - Android

With this code in xml

 android:translationZ="90dp"

Solution 3 - Android

I've been looking through stack overflow to find a good answer and when i couldn't find one i went looking through the docs.

no one seems to have stumbled on this simple answer yet:

ViewCompat.setTranslationZ(view, translationZ);

default translation z is 0.0

Solution 4 - Android

An even simpler solution is to edit the XML of the activity. Use

android:translationZ=""

Solution 5 - Android

bringToFront() is the right way, but, NOTE that you must call bringToFront() and invalidate() method on highest-level view (under your root view), for e.g.:

Your view's hierarchy is:

-RelativeLayout
|--LinearLayout1
|------Button1
|------Button2
|------Button3
|--ImageView
|--LinearLayout2
|------Button4
|------Button5
|------Button6

So, when you animate back your buttons (1->6), your buttons will under (below) the ImageView. To bring it over (above) the ImageView you must call bringToFront() and invalidate() method on your LinearLayouts. Then it will work :) **NOTE: Remember to set android:clipChildren="false" for your root layout or animate-view's gradparent_layout. Let's take a look at my real code:

.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:hw="http://schemas.android.com/apk/res-auto"
    android:id="@+id/layout_parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/common_theme_color"
    android:orientation="vertical" >

    <com.binh.helloworld.customviews.HWActionBar
        android:id="@+id/action_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dimen_actionbar_height"
        android:layout_alignParentTop="true"
        hw:titleText="@string/app_name" >
    </com.binh.helloworld.customviews.HWActionBar>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/action_bar"
        android:clipChildren="false" >

        <LinearLayout
            android:id="@+id/layout_top"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
        </LinearLayout>

        <ImageView
            android:id="@+id/imgv_main"
            android:layout_width="@dimen/common_imgv_height"
            android:layout_height="@dimen/common_imgv_height"
            android:layout_centerInParent="true"
            android:contentDescription="@string/app_name"
            android:src="@drawable/ic_launcher" />

        <LinearLayout
            android:id="@+id/layout_bottom"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
        </LinearLayout>
    </RelativeLayout>

</RelativeLayout>

Some code in .java

private LinearLayout layoutTop, layoutBottom;
...
layoutTop = (LinearLayout) rootView.findViewById(R.id.layout_top);
layoutBottom = (LinearLayout) rootView.findViewById(R.id.layout_bottom);
...
//when animate back
//dragedView is my layoutTop's child view (i added programmatically) (like buttons in above example) 
dragedView.setVisibility(View.GONE);
layoutTop.bringToFront();
layoutTop.invalidate();
dragedView.startAnimation(animation); // TranslateAnimation
dragedView.setVisibility(View.VISIBLE);

GLuck!

Solution 6 - Android

Try FrameLayout, it gives you the possibility to put views one above another. You can create two LinearLayouts: one with the background views, and one with foreground views, and combine them using the FrameLayout. Hope this helps.

Solution 7 - Android

If you are using ConstraintLayout, just put the element after the other elements to make it on front than the others

Solution 8 - Android

i have faced the same problem. the following solution have worked for me.

 FrameLayout glFrame=(FrameLayout) findViewById(R.id.animatedView);
        glFrame.addView(yourView);
        glFrame.bringToFront();
        glFrame.invalidate();

2nd solution is by using xml adding this attribute to the view xml

android:translationZ=""

Solution 9 - Android

You can try to use the bringChildToFront, you can check if this documentation is helpful in the Android Developers page.

Solution 10 - Android

There can be another way which saves the day. Just init a new Dialog with desired layout and just show it. I need it for showing a loadingView over a DialogFragment and this was the only way I succeed.

Dialog topDialog = new Dialog(this, android.R.style.Theme_Translucent_NoTitleBar);
topDialog.setContentView(R.layout.dialog_top);
topDialog.show();

bringToFront() might not work in some cases like mine. But content of dialog_top layout must override anything on the ui layer. But anyway, this is an ugly workaround.

Solution 11 - Android

You can use BindingAdapter like this:

@BindingAdapter("bringToFront")
public static void bringToFront(View view, Boolean flag) {
    if (flag) {
        view.bringToFront();
    }
}


  <ImageView
        ...
        app:bringToFront="@{true}"/>

Solution 12 - Android

The order of the overlapping views really depends of 4 things:

  1. The attribute android:elevation which is measured in dp/sp
  2. The attribute android:translationZ which is also measured in dp/sp.
  3. In Constraint Layout, the order in which you put the views in your Component Tree is also the order to be shown.
  4. The programmatically order that you set through methods like view.bringToFront() in your kotlin/java code.

The numerals 1 and 2 compite with each other and take preference over the points 3 and 4: if you set elevation="4dp" for View 1 and translationZ="2dp" for View 2, View 1 will always be on top regardless of the numerals 3 and 4.

Solution 13 - Android

Thanks to Stack user over this explanation, I've got this working even on Android 4.1.1

((View)myView.getParent()).requestLayout();
myView.bringToFront();

On my dynamic use, for example, I did

public void onMyClick(View v)
     {
     ((View)v.getParent()).requestLayout();
     v.bringToFront();
     }

And Bamm !

Solution 14 - Android

You need to use framelayout. And the better way to do this is to make the view invisible when thay are not require. Also you need to set the position for each and every view,So that they will move according to there corresponding position

Solution 15 - Android

If you are using a LinearLayout you should call myView.bringToFront() and after you should call parentView.requestLayout() and parentView.invalidate() to force the parent to redraw with the new child order.

Solution 16 - Android

Arrange them in the order you wants to show. Suppose, you wanna show view 1 on top of view 2. Then write view 2 code then write view 1 code. If you cant does this ordering, then call bringToFront() to the root view of the layout you wants to bring in front.

Solution 17 - Android

You can use elevation attribute if your minimum api level is 21.

Solution 18 - Android

Try to use app:srcCompat instead of android:src

Solution 19 - Android

You can set visibility to false of other views.

view1.setVisibility(View.GONE);
view2.setVisibility(View.GONE);
...

or

view1.setVisibility(View.INVISIBLE);
view2.setVisibility(View.INVISIBLE);
...

and set

viewN.setVisibility(View.VISIBLE);

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLukapView Question on Stackoverflow
Solution 1 - AndroidMedo ElkamalyView Answer on Stackoverflow
Solution 2 - AndroidKrishnaView Answer on Stackoverflow
Solution 3 - AndroidshrewduView Answer on Stackoverflow
Solution 4 - AndroidTobyView Answer on Stackoverflow
Solution 5 - AndroidJustinView Answer on Stackoverflow
Solution 6 - AndroidEgorView Answer on Stackoverflow
Solution 7 - AndroidFajar Ulin NuhaView Answer on Stackoverflow
Solution 8 - AndroidMudassir KhanView Answer on Stackoverflow
Solution 9 - AndroidEmanuelView Answer on Stackoverflow
Solution 10 - AndroidasozcanView Answer on Stackoverflow
Solution 11 - AndroidAhmad AghazadehView Answer on Stackoverflow
Solution 12 - AndroidCamilo RuizView Answer on Stackoverflow
Solution 13 - AndroidPYKView Answer on Stackoverflow
Solution 14 - AndroidRanjit MishraView Answer on Stackoverflow
Solution 15 - AndroidCristianView Answer on Stackoverflow
Solution 16 - AndroidShuvendu DhalView Answer on Stackoverflow
Solution 17 - AndroidN DroidevView Answer on Stackoverflow
Solution 18 - AndroidgeorgehardcoreView Answer on Stackoverflow
Solution 19 - AndroidthenosicView Answer on Stackoverflow