web-dev-qa-db-fra.com

Placer / superposer (z-index) une vue au-dessus d'une autre vue dans android

J'ai une mise en page linéaire qui consiste en imageview et textview, l'une en dessous de l'autre dans une mise en page linéaire.

<LinearLayout Android:orientation="horizontal" ... >
 <ImageView 
     Android:id="@+id/thumbnail"
     Android:layout_weight="0.8" 
     Android:layout_width="0dip"
     Android:layout_height="fill_parent">
 </ImageView>
 <TextView 
    Android:id="@+id/description"
    Android:layout_weight="0.2"
    Android:layout_width="0dip"
    Android:layout_height="wrap_content">
 </TextView>

Certaines règles peuvent manquer, c'est pour donner une idée de l'apparence de la mise en page. Je veux une autre petite vue textuelle, disons 50dip en longueur et en largeur, placée sur l'imageview, par "plus". Je voulais dire z-index plus que imageview, je veux placer ceci au centre et au-dessus (chevauchement) de l'imageview.

Je veux savoir comment pouvons-nous placer une vue au-dessus de l'autre, avec des indices z variables (de préférence en présentation linéaire)?

213
sat

Vous ne pouvez pas utiliser LinearLayout pour cela, mais vous pouvez utiliser un FrameLayout . Dans un FrameLayout, l'index z est défini par l'ordre dans lequel les éléments sont ajoutés, par exemple:

<FrameLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    >
    <ImageView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:src="@drawable/my_drawable"
        Android:scaleType="fitCenter"
        />
    <TextView
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="bottom|center"
        Android:padding="5dp"
        Android:text="My Label"
        />
</FrameLayout>

Dans ce cas, le TextView serait dessiné au-dessus du ImageView, en bas au centre de l'image.

279
kcoppock
174
diyism

RelativeLayout fonctionne de la même manière, la dernière image de la disposition relative gagne.

62
jt-gilkeson

Changer l'ordre du tirage

Une alternative consiste à modifier l'ordre dans lequel les vues sont dessinées par le parent. Vous pouvez activer cette fonctionnalité à partir de ViewGroup en appelant setChildrenDrawingOrderEnabled (true) et en écrasant getChildDrawingOrder (int childCount, int i) .

Exemple:

/**
 * Example Layout that changes draw order of a FrameLayout
 */
public class OrderLayout extends FrameLayout {

    private static final int[][] DRAW_ORDERS = new int[][]{
            {0, 1, 2},
            {2, 1, 0},
            {1, 2, 0}
    };

    private int currentOrder;

    public OrderLayout(Context context) {
        super(context);
        setChildrenDrawingOrderEnabled(true);
    }

    public void setDrawOrder(int order) {
        currentOrder = order;
        invalidate();
    }

    @Override
    protected int getChildDrawingOrder(int childCount, int i) {
        return DRAW_ORDERS[currentOrder][i];
    }
}

Sortie:

L'appel de OrderLayout#setDrawOrder(int) avec 0-1-2 a pour résultat:

enter image description hereenter image description hereenter image description here

23
Tobrun

Vous pouvez utiliser view.setZ(float) à partir du niveau 21 de l'API. Ici vous pouvez trouver plus d'informations.

16
Vadim Kotov

J'ai résolu le même problème en ajoutant Android:elevation="1dp" à quelle vue vous le souhaitez plutôt qu'un autre. Mais il ne peut pas afficher ci-dessous 5.0, et il aura une petite ombre, si vous pouvez l'accepter, c'est OK.

Donc, la solution la plus correcte est @kcoppock.

11
thirtyyuan

Essayez ceci dans RelativeLayout:

ImageView image = new ImageView(this);
image.SetZ(float z);

Ça marche pour moi.

6
Rizzo

Il existe un moyen d'utiliser LinearLayout. Il suffit de définir le marginTop de votre élément précédent sur la valeur négative correspondante et de s’assurer que l’élément que vous souhaitez placer en haut est situé après l’élément que vous souhaitez insérer dans votre code XML.

<linearLayout Android:orientation="horizontal" ... >
<ImageView 
 Android:id="@+id/thumbnail"
 Android:layout_weight="0.8" 
 Android:layout_width="0dip"
 Android:layout_height="fill_parent"
>
</ImageView>
<TextView 
Android:id="@+id/description"
Android:layout_marginTop="-20dip"
Android:layout_weight="0.2"
Android:layout_width="0dip"
Android:layout_height="wrap_content"
>
</TextView>
5
Tim

Autant que vous puissiez, vous ne pouvez pas le faire avec des mises en page linéaires, vous devrez aller pour RelativeLayout .

4