Comment amener la vue devant tout?


130

J'ai une activité et beaucoup de widgets dessus, certains d'entre eux ont des animations et à cause des animations certains des widgets se déplacent (se traduisent) les uns sur les autres. Par exemple, la vue de texte se déplace sur certains boutons. . .

Maintenant, je veux que les boutons soient toujours sur le devant. Et lorsque la vue de texte se déplace, je veux me déplacer derrière les boutons.

Je ne peux pas y parvenir. J'ai essayé tout ce que je sais, et "bringToFront ()" ne fonctionne définitivement pas.

note Je ne veux pas contrôler l'ordre z par l'ordre de placement de l'élément dans la mise en page car je ne peux tout simplement pas :), la mise en page est complexe et je ne peux pas placer tous les boutons au début de la mise en page


3
J'ai utilisé un RelativeLayoutavec la vue "de dessus" apparaissant en dernier dans le XML. Voir stackoverflow.com/a/31340762/1121497
Ferran Maylinch

Quelqu'un peut-il s'il vous plaît dire le code correspondant en xml de «bringToFront»
Shirish Herwade

Essayez d'utiliser elevation bottomView = elevation: 1dp et topView = elevation: 2dp dans votre xml || ViewCompat.setElevation (View, int)
Tlacaelel Ramon Luis

Réponses:


144

Vous pouvez appeler bringToFront () sur la vue que vous souhaitez obtenir au premier plan

Ceci est un exemple:

    yourView.bringToFront();

4
Résultat inattendu: je l'ai utilisé dans une mise en page linéaire verticale et la vue mise au premier plan est apparue en bas ... Par exemple, j'avais A / B / Cet je voulais mettre Aau premier plan, donc après avoir couru, a.bringToFront()j'ai fini avec une mise en page comme B / C / A.
Ferran Maylinch

2
Donc, j'ai trouvé LinearLayoutne peut pas être utilisé avec bringToFront. J'ai fini par utiliser un fichier RelativeLayout. Voir mon commentaire sur la question elle-même.
Ferran Maylinch

1
Quelqu'un peut-il s'il vous plaît dire le code correspondant en xml de 'bringToFront'
Shirish Herwade

Cela entraîne un repositionnement de l'élément que je déplace vers l'avant pour une raison quelconque. ViewCompat.setTranslationZ(view, 1)fonctionne parfaitement par contre.
Bimde

1
si j'ai utilisé dans le manifeste android: theme = "@ android: style / Theme.Light.NoTitleBar" en activité que yourView.bringToFront (); fonctionne parfaitement, mais j'ai utilisé android: theme = "@ android: style / Theme.AppCompat.Light.NoActionBar" yourView.bringToFront (); ne fonctionne pas. Tout indice sur celui-là.
Rahul

42

J'ai cherché à travers le débordement de pile pour trouver une bonne réponse et quand je n'en trouvais pas une, j'ai parcouru la documentation.

personne ne semble encore être tombé sur cette réponse simple:

ViewCompat.setTranslationZ(view, translationZ);

la traduction par défaut z est 0.0


C'est la position de l'élément sur l'axe Z en px, également appelée élévation. setTranslationX déplacerait la vue le long de l'axe X (gauche / droite), setTranslationY le long de l'axe Y (haut / bas). L'axe Z est le 3ème axe.
xdevs23

Et quoi setZ()? Si je me souviens bien, la position Z de la vue est son élévation plus sa translation Z, après tout.
Gensoukyou1337

2
@ Gensoukyou1337, ViewCompat.setZ(view, yourValueInPixels); view.setZ()ne fonctionne alors que sur l'API 21 et supérieur.
Johnny Five

1
Code Java 8 vérifié dans Android Studio - il ne vérifie que si SDK_INT> = 21, donc pour <21 api, il n'a aucun effet.
Vadim

32

Une solution encore plus simple consiste à éditer le XML de l'activité. Utilisation

android:translationZ=""

3
Ceci n'est utile que dans l'API Android 21 ou supérieur.
isakbob le

25

bringToFront()est la bonne façon, mais, notez que vous devez appeler bringToFront()et invalidate()méthode sur la vue de plus haut niveau (sous votre vue racine), par exemple:

La hiérarchie de votre vue est:

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

Ainsi, lorsque vous animez vos boutons (1-> 6), vos boutons seront sous (ci-dessous) le ImageView. Pour le faire passer (ci-dessus), ImageViewvous devez appeler bringToFront()et invalidate()utiliser la méthode sur votre LinearLayouts. Ensuite, cela fonctionnera :) ** REMARQUE: N'oubliez pas de définir android:clipChildren="false"pour votre mise en page racine ou de gradparent_layout de la vue animée. Jetons un coup d'œil à mon vrai 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>

Un peu de code en .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!


Que faire si vous souhaitez uniquement placer le bouton 6 au-dessus de la vue d'image et pas les autres boutons?
Adam Katz

@AdamKatz: Je pense que vous devez les réorganiser en un autre niveau. Ensuite, amenez-le sur votre chemin.
Justin

merci J'essaie d'apporter un seul élément d'une vue de recycleur au-dessus d'une vue mais laissez les autres éléments en dessous, assez coincé!
Adam Katz

J'ai utilisé la même chose. Son fonctionne bien avec un seul problème qu'il cache la barre d'outils.
user2980181

Cela fonctionne-t-il avec plusieurs niveaux? Disons que j'ai un ConstraintLayoutqui contient un RelativeLayout, et un autre RelativeLayout, les deux ont la même taille que sa racine ConstraintLayout( match_parent). Le premier RelativeLayouta un Button, et est également derrière (dans l'ordre z) le second RelativeLayout. Puis-je faire Buttonen sorte que le premier RelativeLayoutapparaisse comme s'il était au-dessus de tout, de sorte qu'il soit visible et cliquable, en utilisant View::bringToFront()?
oaskamay

25

Avec ce code en xml

 android:translationZ="90dp"

3
D'où 90dpvient-il?
Sudhir Khanger

1
c'est une saisie manuelle. Vous pouvez essayer avec en fonction de vos besoins. soit 45dp ou 135dp ou 180dp ou 270dp
Krishna

Ne pourriez-vous pas simplement utiliser 1dp?
Tyler Turnbull le

18

Essayez FrameLayout, cela vous donne la possibilité de mettre les vues les unes au-dessus des autres. Vous pouvez en créer deux LinearLayouts: une avec les vues d'arrière-plan et une avec des vues de premier plan, et les combiner à l'aide de FrameLayout. J'espère que cela t'aides.


1
Comment pouvons-nous l'amener au sommet comme un dialogue?
Gaurav Arora

@Infinity, vous pouvez créer un FragmentDialog à cet effet, ou simplement utiliser le Theme.Dialog pour votre activité.
Egor

Je ne peux pas utiliser FragmentDialog car il est incompatible avec l'API 10. Deuxièmement, j'utilise déjà un thème pour mon application. Est-ce qu'il y a un autre moyen ? Je l'ai utilisé FrameLayout comme vous l'avez dit!
Gaurav Arora

@Infinity, vous pouvez utiliser la version de bibliothèque de compatibilité de FragmentDialog, qui est disponible à partir de l'API 4.
Egor

8

Si vous utilisez ConstraintLayout, placez simplement l'élément après les autres éléments pour le faire à l'avant que les autres



3

Il peut y avoir un autre moyen qui sauve la mise. Ouvrez simplement une nouvelle boîte de dialogue avec la mise en page souhaitée et montrez-la simplement. J'en ai besoin pour afficher un loadingView sur un DialogFragment et c'était la seule façon de réussir.

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

bringToFront () peut ne pas fonctionner dans certains cas comme le mien. Mais le contenu de la disposition dialog_top doit remplacer tout ce qui se trouve sur la couche d'interface utilisateur. Mais de toute façon, c'est une solution de contournement laide.


3

j'ai fait face au même problème. la solution suivante a fonctionné pour moi.

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

La deuxième solution consiste à utiliser xml en ajoutant cet attribut à la vue xml

android:translationZ=""

2

Vous pouvez utiliser BindingAdapter comme ceci:

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


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

0

Vous devez utiliser framelayout. Et la meilleure façon de faire est de rendre la vue invisible lorsque cela n'est pas nécessaire. Vous devez également définir la position pour chaque vue, afin qu'elles se déplacent en fonction de la position correspondante


0

Si vous utilisez a, LinearLayoutvous devez appeler myView.bringToFront()et après, vous devez appeler parentView.requestLayout()et parentView.invalidate()forcer le parent à redessiner avec le nouvel ordre enfant.


0

Essayez d'utiliser l'élévation dessus, quelque chose comme yourview.setElevation(5);


0

Merci à l' utilisateur de Stack pour cette explication, cela fonctionne même sur Android 4.1.1

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

Sur mon utilisation dynamique, par exemple, j'ai fait

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

Et Bamm!


-2

Disposez-les dans l'ordre que vous souhaitez afficher. Supposons que vous vouliez afficher la vue 1 en haut de la vue 2. Ensuite, écrivez le code de la vue 2, puis écrivez le code de la vue 1. Si vous ne pouvez pas effectuer cet ordre, appelez bringToFront () à la vue racine de la mise en page que vous souhaitez mettre en avant.


-32

Vous pouvez définir la visibilité sur false pour les autres vues.

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

ou

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

Et mettre

viewN.setVisibility(View.VISIBLE);

4
J'ai besoin que tout soit visible, ce n'est pas le problème, le problème est l'ordre z. si la viabilité était le problème, il serait trop facile à résoudre. . .
Lukap
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.