Androidで別のビューの上にビューを配置/オーバーラップ(z-index)


230

imageviewとtextviewで構成される線形レイアウトがあり、線形レイアウトで上下に配置されています。

<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>

いくつかのルールが欠落している可能性があります。これは、レイアウトがどのように見えるかを示すためです。私は長さと幅が50dipの別の小さなテキストビューをイメージビューの上に配置したいと思います。「オーバー」とは、イメージビューよりもZ-indexの方が大きいことを意味します。

Zインデックスを変えて(できれば線形レイアウトで)1つのビューを他のビューの上に配置する方法を知りたいですか?

回答:


295

これにはLinearLayoutを使用できませんが、を使用できますFrameLayout。のFrameLayout場合、Zインデックスは、アイテムが追加される順序によって定義されます。次に例を示します。

<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>

この場合、TextViewはImageViewの上に、画像の下部中央に沿って描画されます。


ええ、ドキュメントを調べた後、フレームレイアウト自体を使用してそれを行いました。ありがとうございました。
2011年

11
これにRelativeLayoutの代わりにFrameLayoutを使用する利点はありますか?
Ixx

12
FrameLayoutは、グループ内の他のビューとは関係なく、親に関してそれらをレイヤー化するだけです。RelativeLayoutは、他のアイテムを基準に配置するためのものです。
Kevin Coppock

3
こんにちはkcoppock私のモバイル(hdpi)はフレームレイアウトでzオーダーを尊重していませんが、他(xhdpi)があり、このオーダーを尊重しています。なぜこれを行うのか知っていますか?前もって感謝します!:D
–MerlíEscarpenterPérez2015

1
API 21 / KitKat以降、setZとtranslationZを使用できるようになりました。FrameLayoutハックは必要なくなりました(ついに!)。これは、近代的な5.0+開発のための好適な答えのようになります。stackoverflow.com/a/29703860/358578は
pbarranis

183

3
これをxmlファイルでも使用できますか?
広告

2
翻訳アニメーション中にitz zindexを変更するためのビューをもたらすようなものを探していました。
DeltaCap019 2013年

翻訳アニメーションの解決策はありますか?
nAkhmedov 2014

9
bringChildToFront()は、親の内部のビューのインデックスを変更するだけです
Zar E Ahmer

4
これは全体のレイアウト順序を
ねじ込み

66

RelativeLayoutも同じように機能し、相対レイアウトの最後の画像が優先されます。


14
標高を使用しない限り、その中で最大の値も必要です。
Sami Kuhmonen

5
この質問は、昇格が存在する前に行われ、回答されました。アプリのminSdkがLollipop未満の場合、標高を使用しても問題は解決しません(ロリポップ前の携帯電話では、標高のみに依存している場合、レイアウトは正しく表示されません)-レイアウトの順序に注意を払う必要があります。ただし、下部のコンポーネントで標高を使用する場合は、少なくとも上部と同じかそれ以上の高さが必要です。
jt-gilkeson

27

描画順序の変更

別の方法は、親によってビューが描画される順序を変更することです。この機能をViewGroupから有効にするには、setChildrenDrawingOrderEnabled(true)呼び出し、getChildDrawingOrder(int childCount、int i)をオーバーライドします。

例:

/**
 * 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];
    }
}

出力:

OrderLayout#setDrawOrder(int)0-1-2で呼び出すと、次の結果になります。

ここに画像の説明を入力してください ここに画像の説明を入力してください ここに画像の説明を入力してください


アクティビティのonCreate()でsetDrawOrder(i)を呼び出しますか?XMLに6つのウィジェットがある場合、DRAW_ORDERSの各行を6つの数値(0〜5)の配列で初期化する必要がありますか?
John Ward

上記の@JohnWardレイアウトは単なる例であり、getChildDrawingOrder()で独自の動作を定義できます。
Tobrun 2017年

ここに、明確なコードを含む関連する投稿があります:stackoverflow.com/questions/20524162/framelayout-in-reverse
Robert

20

view.setZ(float)APIレベル21から使用できます。詳細については、こちらをご覧ください。


3
これは、API 21 / KitKat / 5.0以降で推奨される答えです。古いframeLayoutハックはありがたいことにもう必要ありません。個人的に私はsetZとtranslationZの違いを理解していませんが、後者は属性であり、美しく機能しました。ありがとう!
pbarranis

以前のAPIでは、ViewCompat#setZ()も使用できます。
Ali Yucel Akgul

@AliYucelAkgul ここのドキュメントを見ると、わかり Compatibility: API < 21: No-op ます。だから私はそれはうまくいかないと思います
Vadim Kotov

@VadimKotov、私は自分のアプリで試しましたが、うまくいきます。
Ali Yucel Akgul

@AliYucelAkgulよく、それは奇妙です。おそらくドキュメントの間違いですか?APIが21未満で機能していると100%確信していますか?私はそれが以前のAPIのビューの順序を変えることができるという考えを持っていませんが、標高のような何も派手なもの、など。
ヴァディムコトフ

14

追加することで同じ問題を解決しました android:elevation="1dp"あなたが望むビューに別のビューをことで。ただし、5.0未満では表示できず、影が少し表示されます。許容できる場合は問題ありません。

それで、@ kcoppockである最も正しい解決策は言いました。


7

RelativeLayoutでこれを試してください:

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

わたしにはできる。


2
あなたはもう少し説明する必要があります。たとえば、このコードをどこに配置しますか?
DevB2F 2017年

まあ、私はそれをOnCreate()メソッドに入れました。追加された各画像には、以前に追加された画像よりも優先されるzインデックスがあります。つまり、zインデックスを使用して、前の後ろの次の位置を変更できます。
Rizzo、2017

5

LinearLayoutを使用する方法があります。前の要素のmarginTopを対応する負の値に設定し、上に配置したい要素が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>

4

私の知る限り、あなたが線形レイアウトでそれを行うことができない、あなたがのために行く必要がありますRelativeLayout


RelativeLayoutはframeLayoutを拡張しません。それが機能しますか?
ekatz

そうなる。FrameLayoutまたはRelativeLayoutのいずれかを使用できます。子ビューを配置する方法はそれぞれ異なります。これらのレイアウトの詳細については、ドキュメントを参照してください。
Vincent Mimoun-Prat、2012

これが先の方法です
アルバートジェームズテディ


0

必要なときに1つのビューだけを前面に表示したい場合は、これを使用します。

containerView.bringChildToFront(topView);

containerViewは、ソートされるビューのコンテナです。topViewは、コンテナーの最上位たいビューです。

複数のビューを配置するには、前述のようにsetChildrenDrawingOrderEnabled(true)を使用してgetChildDrawingOrder(int childCount、int i)をオーバーライドします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.