Androidの「高度」に影が表示されない


273

ListViewがあり、各リストアイテムの下に影を表示します。私はAndroid Lollipopの新しい標高機能を使用して、影を落とすビューにZを設定し、ActionBar(技術的にはLollipopのツールバー)でこれを効果的に実行しています。Lollipopの標高を使用していますが、何らかの理由でリストアイテムの下に影が表示されません。次に、各リストアイテムのレイアウトを設定する方法を示します。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    style="@style/block"
    android:gravity="center"
    android:layout_gravity="center"
    android:background="@color/lightgray"
    >

    <RelativeLayout
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:layout_marginLeft="40dp"
        android:layout_marginRight="40dp"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:elevation="30dp"
        >

        <ImageView
            android:id="@+id/documentImageView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop" />

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/alphared"
            android:layout_alignParentBottom="true" >

            <appuccino.simplyscan.Extra.CustomTextView
                android:id="@+id/documentName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/white"
                app:typeface="light"
                android:paddingLeft="16dp"
                android:paddingTop="8dp"
                android:paddingBottom="4dp"
                android:singleLine="true"
                android:text="New Document"
                android:textSize="27sp"/>

            <appuccino.simplyscan.Extra.CustomTextView
                android:id="@+id/documentPageCount"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/white"
                app:typeface="italic"
                android:paddingLeft="16dp"
                android:layout_marginBottom="16dp"
                android:text="1 page"
                android:textSize="20sp"/>

        </LinearLayout>

    </RelativeLayout>

</RelativeLayout>

ただし、影のないリストアイテムが次のように表示されます。 ここに画像の説明を入力してください

私も役に立たないように以下を試しました:

  1. 標高を親レイアウトではなく、ImageViewおよびTextViews自体に設定します。
  2. ImageViewに背景を適用しました。
  3. 高度の代わりにTranslationZを使用しました。

(customviewsなしで)レイアウトを試してみて、電話に影を表示しましたが、問題を再現する最小限のプロジェクトを共有できますか?
rnrneverdies 2014


回答:


384

私はLollipopでシャドウを少し遊んでいますが、これは私が見つけたものです。

  1. ViewGroupの境界が何らかの理由でその子の影を遮断しているようです。そして
  2. で設定されたシャドウandroid:elevationView、マージンを介して拡張された境界ではなく、の境界によってカットオフされます。
  3. 子ビューにシャドウを表示させる正しい方法は、親にパディングを設定し、その親に設定android:clipToPadding="false"することです。

これが私が知っていることに基づいたあなたへの私の提案です:

  1. トップレベルRelativeLayoutを設定して、影を表示したい相対レイアウトで設定したマージンと同じパディングを設定します。
  2. android:clipToPadding="false"同じ上に設定しRelativeLayoutます。
  3. RelativeLayout標高も設定されているからマージンを削除します。
  4. [編集]標高を必要とする子レイアウトに不透明な背景色を設定する必要があるかもしれません。

結局のところ、トップレベルの相対レイアウトは次のようになります。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    style="@style/block"
    android:gravity="center"
    android:layout_gravity="center"
    android:background="@color/lightgray"
    android:paddingLeft="40dp"
    android:paddingRight="40dp"
    android:paddingTop="20dp"
    android:paddingBottom="20dp"
    android:clipToPadding="false"
    >

内部相対レイアウトは次のようになります。

<RelativeLayout
    android:layout_width="300dp"
    android:layout_height="300dp"
    android:background="[some non-transparent color]"
    android:elevation="30dp"
    >

8
これをありがとう!また、android:clipChildren = "false"が親の相対レイアウトに適用されると便利であることがわかりました。
blaffie 2015年

1
@blaffieを助けてくれてうれしい!
Justin Pollard

214
グーグルがそのようなお粗末なコードを生成するのは非常に迷惑です。これらのフレームワークのバグを何年も説明する必要があります。
ミゲル2015年

8
グーグルは(alas)だけを言います:「影は昇格されたビューの親によって描かれるので、デフォルトで親によってクリッピングされる標準のビュークリッピングの対象となります。
John

5
私の場合は透明色でした。
わかりました

286

背景のないビューがある場合、この線が役立ちます

android:outlineProvider="bounds"

デフォルトでは、影はビューの背景によって決定されるため、背景がない場合、影もありません。


11
なんと奇妙なことに、プレビューでは標高が表示されましたが、実際のデバイスでは表示されませんでした。ありがとう、これで問題が解決しました。
Ioane Sharvadze、2016

APIレベル21以上で機能
Pantelis Ieronimakis

10
この種類は私のために働いたが、textviewに適用されたときに両側に斜めの境界線を与えた 背景を色(親の背景色と同じ)に設定すると、より効果的に機能します。
Gober、2016年

4
これは、背景がカスタムでがない場合にも適用されます<solid>
David Lord、

これは逆に使用できます。高度のある不透明な背景が必要で、影は必要ない場合。単にに設定してくださいnone。ありがとう!
Odys

101

どうやら、ビューに標高を設定してそれを表示させることはできません。背景も指定する必要があります。

LinearLayoutに追加された次の行は、最終的に影を示しました。

android:background="@android:color/white"
android:elevation="10dp"

意外でした。ImageViewをsrcで設定し、解決策を探していました。ありがとうございました。
Andrew Grow、

47

注意すべきもう1つのことは、マニフェストにこの行がある場合、影は表示されません。

android:hardwareAccelerated = "false"

私は提案されたものをすべて試しましたが、線を削除したときにのみ機能しました。線があった理由は、アプリが多数のビットマップ画像で動作し、アプリがクラッシュするためでした。


1
そのフラグが存在する必要がある場合、これは問題を解決しません。
Clive Jefferies 2017年

ありがとうございました!!AppBarを昇格させるために1日を費やし、このアクティビティフラグのマニフェストを確認したところ問題が見つかりました
ir2pid

1
可能な解決策はすべて試しましたが、どれもうまくいきませんでした。このソリューションは機能しました。ありがとう。android:clipToPadding="false"このソリューションも必要です。
Chirag Savsani

29

背景のないビューがある場合、この線が役立ちます

android:outlineProvider="bounds"

背景付きのビューがある場合、この線が役立ちます

android:outlineProvider="paddedBounds"

6
この解決策が私にとって有効な唯一のものです。ありがとう
Oleh Liskovych

4
これは、ビューの背景に半径がない場合は機能します。その場合、影は長方形として表示されますが、paddedBoundsは背景のあるビューでは機能します。
Trevor Hart

android:outlineProvider="paddedBounds"このラインは私のために働いた。Selector Drawableを設定します。
Chirag Savsani

1
これを使用した場合、影はビューの外側ではなく完全に内側に描画されます。これは私が望んでいることではありません。
androidguy


12

ええと、これを理解するために1時間費やしました。私の場合、背景が設定されていましたが、色に設定されていました。これでは不十分です。ビューの背景を描画可能に設定する必要があります。

たとえば、これには影がありません:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="165dp"
    android:background="@color/ight_grey"
    android:elevation="20dp"
    android:orientation="vertical"
    />

しかし、これは

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="165dp"
    android:background="@drawable/selector_grey"
    android:elevation="20dp"
    android:orientation="vertical"
    />

編集:セレクターを背景として使用する場合、コーナーが設定されていないと影がプレビューウィンドウに表示されませんが、デバイスには表示されます。

例:プレビューに影がありません:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
            <stroke
                android:width="1dp"
                android:color="@color/grey"/>
        </shape>
    </item>
</selector>

しかしこれはします:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/white" />
            <corners android:radius="1dp" />
            <stroke
                android:width="1dp"
                android:color="@color/grey"/>
        </shape>
    </item>
</selector>

1
最初のポイントの正反対がRecyclerViewアイテムで私に当てはまりました...プロのAndroid開発の5年間後にこれらのAPIと戦わなければならないケースを見つけるのは驚くべきことです:(
aProperFox

7

背景色を追加すると役に立ちました。

<CalendarView
    android:layout_width="match_parent"
    android:id="@+id/calendarView"
    android:layout_alignParentTop="true"
    android:layout_alignParentStart="true"
    android:layout_height="wrap_content"
    android:elevation="5dp"

    android:background="@color/windowBackground"

    />

4

時々動作するように、background="@color/***"または動作しbackground="#ff33**"ない場合、私background_colorはドローアブルに置き換え、それは動作します


4

それでも標高が表示されない場合は、

    android:hardwareAccelerated="true" 

これは間違いなくあなたを助けます。


これで解決しました。私はTRUEがデフォルト設定であると想定していましたが、少なくとも私の場合はそうではないようです。
Matt Robertson

3

透明な背景が必要でandroid:outlineProvider="bounds"機能しない場合は、カスタムViewOutlineProviderを作成できます。

class TransparentOutlineProvider extends ViewOutlineProvider {

    @Override
    public void getOutline(View view, Outline outline) {
        ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
        Drawable background = view.getBackground();
        float outlineAlpha = background == null ? 0f : background.getAlpha()/255f;
        outline.setAlpha(outlineAlpha);
    }
}

そして、このプロバイダーを透明なビューに設定します。

transparentView.setOutlineProvider(new TransparentOutlineProvider());

出典:https : //code.google.com/p/android/issues/detail?id=78248#c13

[編集] Drawable.getAlpha()のドキュメントは、Drawableがアルファを脅かす方法に固有であると述べています。常に255を返す可能性があります。この場合、アルファを手動で指定できます。

class TransparentOutlineProvider extends ViewOutlineProvider {

    private float mAlpha;

    public TransparentOutlineProvider(float alpha) {
        mAlpha = alpha;
    }

    @Override
    public void getOutline(View view, Outline outline) {
        ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
        outline.setAlpha(mAlpha);
    }
}

ビューの背景が、アルファDDx0 / FFx0 == 0.86のデフォルト色#DDFF0000のStateListDrawableである場合

transparentView.setOutlineProvider(new TransparentOutlineProvider(0.86f));

2

レイアウトに背景色を与えてください:

    android:background="@color/catskill_white"
    android:layout_height="?attr/actionBarSize"
    android:elevation="@dimen/dimen_5dp"

1

clipChildren="false"親のレイアウトの設定で運が良かったです。


1

少し時間をかけて作業しましたが、最終的に背景が暗いと影が見えないことに気付きました


1

受け入れられた回答に加えて、電話のBluelightフィルター機能がオンの場合、標高が期待どおりに機能しない可能性があるため、もう1つの理由があります。

私のデバイスで標高が完全に歪んでいて耐えられないように見えたとき、私はこの問題に直面していました。しかし、プレビューでは標高は問題ありませんでした。電話でBluelightフィルターをオフにすることで問題は解決しました。

だから設定後

android:outlineProvider="bounds"

標高が正しく機能していない場合は、電話の色設定をいじくり回してみてください。


0

あなたの問題は、親を埋める相対レイアウトに標高要素を適用したことに起因していると思います。その親は、独自の描画キャンバス内のすべての子ビューをクリップします(子の影を処理するビューです)。これを修正するにRelativeLayoutは、ビューのxmlの最上位(ルートタグ)に標高プロパティを適用します。


0

私の場合、フォントが問題でした。

1)なしfontFamilyandroid:background、ある値に設定する必要がありました。

<TextView
    android:layout_width="match_parent"
    android:layout_height="44dp"
    android:background="@android:color/white"
    android:elevation="3dp"
    android:gravity="center"
    android:text="@string/fr_etalons_your_tickets"
    android:textAllCaps="true"
    android:textColor="@color/blue_4" />

2)設定fontFamilyを追加android:outlineProvider="bounds"する必要がありました:

<TextView
    android:fontFamily="@font/gilroy_bold"
    android:layout_width="match_parent"
    android:layout_height="44dp"
    android:background="@android:color/white"
    android:elevation="3dp"
    android:gravity="center"
    android:outlineProvider="bounds"
    android:text="@string/fr_etalons_your_tickets"
    android:textAllCaps="true"
    android:textColor="@color/blue_4" />

0

私の場合、これは、レンダリングレイヤータイプを「ソフトウェア」に設定するカスタムの親コンポーネントが原因でした。

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

この行を削除すると、トリックが行われました。または、なぜこれが最初に存在するのかを評価する必要があります。私の場合、それはHoneycombをサポートすることでした。これは、私のプロジェクトの現在の最小SDKよりもかなり遅れています。


0

また、そのビューでアルファを変更しないかどうかも確認してください。標高のある一部のビューでアルファを変更するときの問題を調査しています。アルファが変更され、1fに戻されると、標高は緩くなります。

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