web-dev-qa-db-fra.com

Comment envoyer la vue à l'arrière? Comment contrôler l'ordre z par programme?

J'ai un problème pour envoyer la vue à l'arrière. Dans Android, nous avons une méthode comme bringToFront(), pour placer la vue au-dessus d'une autre vue. Comme ça, je veux mettre la vue en dessous de l'image précédente. 

Existe-t-il une méthode telle que sendToBack() ou bringToBack() dans Android? Si oui, quelqu'un peut-il m'aider dans ce domaine? 

Remarque: comme je ne souhaite pas contrôler l'ordre z par l'ordre de placement des éléments dans la présentation, je souhaite contrôler l'ordre z par programme. 

Je ne veux pas cacher les vues sur le devant, je veux juste qu'elles soient derrière la vue qui bouge. 

49
Lukap

Afaik il n'y a pas de solution intégrée pour cela. Je suppose que vous essayez de modifier l'ordre z dans un FrameLayout ou quelque chose de similaire.

Cependant, je pense que vous pouvez modifier l'ordre des éléments enfants contenus dans la présentation. Les méthodes RemoveChild ... () et addView () peuvent prendre des valeurs de position. Vous pouvez donc très probablement échanger des éléments enfants, ce qui modifierait l'ordre z. Cela semble un peu hacky solution cependant.

Ou envisagez de modifier la propriété de visibilité des vues enfant, vous pouvez obtenir un comportement similaire et ce serait beaucoup plus propre, je pense.

Modifier:

Avec la nouvelle version Android, L Developer Preview, il semble que nous ayons enfin la possibilité de changer facilement le classement Z des vues. Les propriétés 'Elevation' et 'TranslationZ' à la rescousse: https://developer.Android.com/preview/material/views-shadows.html

30

Je me rends compte que cela a été impliqué dans d'autres réponses, mais personne n'a posté le code. Je conserve les éléments suivants dans une classe d’utilitaires où j’ai des fonctions "d’aide" pour traiter les vues:

public static void sendViewToBack(final View child) {
    final ViewGroup parent = (ViewGroup)child.getParent();
    if (null != parent) {
        parent.removeView(child);
        parent.addView(child, 0);
    }
}
61
Turix

Il n'y a pas de méthode sendToBack(). Mais si vous appelez bringToFront() sur la vue positionnée plus bas, vous obtenez presque le même effet.

38
Pepijn

Appelez bringToFront() sur la vue à placer au premier plan, puis appelez la méthode invalidate() sur toutes les vues, y compris celle que vous voulez au premier plan. Répétez la même chose pour tous les auditeurs.

Ainsi, lorsqu'un auditeur d'une autre vue sera appelé, la vue précédente sera invalidée et sera en arrière-plan.

19
noob

Voici la méthode que j'utilise pour envoyer une vue à l'arrière (donc opposé à bringToFront, sorte d'envoiSoBack)

    private void moveToBack(View myCurrentView) 
    {
        ViewGroup myViewGroup = ((ViewGroup) myCurrentView.getParent());
        int index = myViewGroup.indexOfChild(myCurrentView);
        for(int i = 0; i<index; i++)
        {
            myViewGroup.bringChildToFront(myViewGroup.getChildAt(i));
        }
    }

J'espère que cela t'aides!

8
Al-Noor Ladhani

Veuillez noter que vous pouvez utiliser view.setZ(float) à partir de l’API niveau 21. Ici vous pouvez trouver plus d’informations.

2
Vadim Kotov

cela fonctionne bien comme rapporter ()

public void moveToBack(ViewGroup viewGroup, View v) {
    int s = 1;
    for (int i = 1; i < viewGroup.getChildCount(); i++) {
        if (viewGroup.getChildAt(1) == v) {
            s = 2;
        } else {
            viewGroup.getChildAt(s).bringToFront();
        }
    }
}
1
Behnam Tajadini

Dans votre fichier XML, vous devez écrire dans l'ordre:

<FrameLayout
Android:id="@+id/frameLayoutXML"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical"
<ImageView
 Android:id="@+id/imageViewXML"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
<Android.support.design.widget.FloatingActionButton
Android:id="@+id/floatB_XML"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center" />
</FrameLayout>

Dans ce cas, la imageView sera de retour de la FloatingActionButton.

Si vous voulez changer quelque chose et que vous le ferez par programme, alors:

public class SomeActivity extends AppCompatActivity {

    //declare variables
    ImageView imageView;
    FrameLayout frameLayout;
    FloatingActionButton floatingActionButtonNew;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //Here is to call what already exists at XML file
        frameLayout=findViewById(R.id.frameLayoutXML);   
        imageView = findViewById(R.id.imageViewXML);
        //Here is to declare a new Element to add to the view, but is not at XML File
        floatingActionButtonNew=New FloatingActionButton(this);
        frameLayout.removeAllViews();  //here you remove all views.
        frameLayout.addView(imageView);//And you add again the imageView first
        floatingActionButtonNew.setLayoutParams(new 
         RelativeLayout.LayoutParams(
          RelativeLayout.LayoutParams.WRAP_CONTENT,
          RelativeLayout.LayoutParams.WRAP_CONTENT
        )); //Then you can give some format to your floatingButtonNew

        //And finally  add to the frameLayout the new View in this case the floatingButtonNew
        frameLayout.addView(floatingActionButtonNew);
    }
}

Dans cet ordre de déclaration, vous retrouverez l'image du bouton flottant. Ainsi, la vue déclarée en premier sera renvoyée de la vue déclarée en second lieu, et la clé permettant d'exécuter l'ordre est d'exécuter removeAllViews d'une FrameLayout ou LinearLayout et d'ajouter à nouveau cette vue lorsque vous ajoutez par programme.

1
Vero Gorena

Vous pouvez également essayer d'utiliser les fonctionnalités de la méthode ViewGroup.addViewInLayout() qui prennent un index, en déterminant si la vue doit être à la fin ou au début de la liste.

1
teoREtik

Vous pouvez essayer de faire view.setVisibility(View.INVISIBLE) ou view.setVisibility(View.GONE).

METTRE À JOUR:

Ceci vous montre comment accomplir ce que vous voulez faire.

0
A. Abiri

Si vous utilisez la bibliothèque appCompat, il existe un autre moyen de modifier l'ordre Z pour les périphériques inférieurs à 21 API:

ViewCompat.setTranslationZ(view, zValue);
0
Fragment

Je voudrais soit mettre sa visibilité à 0 ou tout simplement mettre la vue en dessous. 

0