web-dev-qa-db-fra.com

Android "élévation" ne montrant pas une ombre

J'ai un ListView, et avec chaque élément de la liste je veux qu'il montre une ombre en dessous. J'utilise la nouvelle fonction d'élévation d'Android Lollipop pour définir un Z sur la vue que je veux projeter comme une ombre, et je le fais déjà efficacement avec la barre de contrôle (techniquement une barre d'outils dans Lollipop). J'utilise l'élévation de Lollipop, mais pour une raison quelconque, elle ne montre pas d'ombre sous les éléments de la liste. Voici comment la disposition de chaque élément de liste est configurée:

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

Cependant, voici comment il affiche l’élément de la liste, sans ombre: enter image description here

J'ai également essayé ce qui suit en vain:

  1. Définissez l’altitude sur ImageView et TextViews eux-mêmes au lieu de la disposition parent.
  2. Appliqué un arrière-plan à ImageView.
  3. TranslationZ utilisé à la place de Elevation.
213
AggieDev

J'ai un peu joué avec les ombres sur Lollipop et voici ce que j'ai trouvé: 

  1. Il semble que les limites d'un parent ViewGroup coupent l'ombre de ses enfants pour une raison quelconque; et
  2. les ombres définies avec Android:elevation sont coupées par les limites de la variable View, et non par celles étendues dans la marge;
  3. la bonne façon d'obtenir une vue enfant pour afficher l'ombre est de définir le remplissage sur le parent et de définir Android:clipToPadding="false" sur ce parent.

Voici ma suggestion basée sur ce que je sais:

  1. Définissez votre RelativeLayout de niveau supérieur pour que le remplissage soit égal aux marges que vous avez définies dans la présentation relative que vous souhaitez afficher dans l’ombre;
  2. mettre Android:clipToPadding="false" sur la même RelativeLayout;
  3. Supprimez la marge de la RelativeLayout qui comporte également un ensemble d'altitude;
  4. [MODIFIER], vous devrez peut-être également définir une couleur d'arrière-plan non transparente sur la disposition enfant qui nécessite une élévation.

À la fin de la journée, votre disposition relative de niveau supérieur devrait ressembler à ceci:

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

La disposition relative intérieure devrait ressembler à ceci:

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

Si vous avez une vue sans arrière-plan, cette ligne vous aidera

Android:outlineProvider="bounds"

Par défaut, l'ombre est déterminée par l'arrière-plan de la vue. Par conséquent, s'il n'y a pas d'arrière-plan, il n'y aura pas d'ombre. 

240
Dmitry Ryadnenko

Apparemment, vous ne pouvez pas simplement définir une élévation sur une vue et la faire apparaître. Vous devez également spécifier un arrière-plan.

Les lignes suivantes ajoutées à mon LinearLayout ont finalement montré une ombre:

Android:background="@Android:color/white"
Android:elevation="10dp"
75
John Slavick

une autre chose que vous devez savoir, les ombres ne seront pas visibles si vous avez cette ligne dans le manifeste:

Android: hardwareAccelerated = "false"

J'ai essayé tous les éléments suggérés, mais cela n'a fonctionné que lorsque j'ai supprimé la ligne, parce que mon application fonctionnait avec plusieurs images bitmap et provoquait son blocage.

34
nada

Si vous ajoutez l'altitude à un élément de bouton, vous devez ajouter la ligne suivante:

Android:stateListAnimator="@null"

Voir Android 5.0 Android: élévation Fonctionne pour View, mais pas Button?

16
user8102108

Ugh, je viens de passer une heure à essayer de comprendre cela. Dans mon cas, mon arrière-plan était défini, mais sa couleur était définie. Cela ne suffit pas, vous devez définir l’arrière-plan de la vue comme dessinable. 

par exemple. Cela n'aura pas d'ombre: 

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

mais ce sera

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

EDIT: J'ai également découvert que si vous utilisez un sélecteur comme arrière-plan, si vous n'avez pas défini de coin, l'ombre n'apparaîtra pas dans la fenêtre Aperçu mais elle apparaîtra dans le dispositif

par exemple. Cela n'a pas d'ombre dans l'aperçu:

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

mais cela fait:

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

Si vous avez une vue sans arrière-plan, cette ligne vous aidera

Android:outlineProvider="bounds"

Si vous avez une vue en arrière-plan, cette ligne vous aidera

Android:outlineProvider="paddedBounds"
11
Deepak sharma

L'ajout de couleur de fond m'a aidé.

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

    />
6
Tim Glenn

Parfois, comme background="@color/***" ou background="#ff33**" ne fonctionne pas, je remplace background_color par drawable, alors cela fonctionne

3
ray liu

Si vous souhaitez un fond transparent et que Android:outlineProvider="bounds" ne fonctionne pas pour vous, vous pouvez créer un ViewOutlineProvider personnalisé:

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);
    }
}

Et définissez ce fournisseur sur votre vue transparente:

transparentView.setOutlineProvider(new TransparentOutlineProvider());

Sources: https://code.google.com/p/Android/issues/detail?id=78248#c13

[EDIT] La documentation de Drawable.getAlpha () indique qu’elle est spécifique à la façon dont le Drawable menace l’alpha. Il est possible qu'il renvoie toujours 255 . Dans ce cas, vous pouvez fournir l'alpha manuellement:

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);
    }
}

Si l'arrière-plan de votre vue est un StateListDrawable avec la couleur par défaut # DDFF0000 c'est-à-dire avec alpha DDx0/FFx0 == 0.86

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

donner une couleur de fond à la mise en page a travaillé pour moi

    Android:background="@color/catskill_white"
    Android:layout_height="?attr/actionBarSize"
    Android:elevation="@dimen/dimen_5dp"
2
sudhakara

En plus de la réponse acceptée, il existe une raison supplémentaire pour laquelle l’élévation peut ne pas fonctionner comme prévu.

Si le filtre Bluelight du téléphone est activé

Je faisais face à ce problème lorsque l'altitude est apparue complètement déformée et insupportable dans mon appareil. Mais l'altitude était bien dans l'aperçu. Désactiver le filtre Bluelight sur le téléphone a résolu le problème.

Donc même après la mise

Android:outlineProvider="bounds"

L'élévation ne fonctionne pas correctement, alors vous pouvez essayer de bricoler les paramètres de couleur du téléphone.

1
Hemang Kumar

Si l'altitude ne s'affiche toujours pas, essayez

    Android:hardwareAccelerated="true" 

cela va certainement vous aider.

1
Rohit Lalwani

Dans mon cas, cela était dû à un composant parent personnalisé qui définissait le type de couche de rendu sur "Logiciel":

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

Enlever cette ligne de fait le tour. Bien entendu, vous devez évaluer pourquoi cela existe en premier lieu. Dans mon cas, il s'agissait de supporter Honeycomb, qui est bien en retard par rapport au SDK minimum actuel pour mon projet.

0
ErrricP

Je pense que votre problème découle du fait que vous avez appliqué l'élément altitude à une mise en page relative remplissant son parent. Son parent coupe toutes les vues enfant dans sa propre zone de dessin (et est la vue qui gère l'ombre de l'enfant). Vous pouvez résoudre ce problème en appliquant une propriété d'altitude à la plus haute RelativeLayout de votre vue xml (balise racine).

0
FluffyC4n't

Dans mon cas, les polices étaient le problème. 

1) Sans fontFamily je devais définir Android:background à une valeur.

<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) avec fontFamily je devais ajouter le paramètre 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
soshial

J'ai eu de la chance avec la définition de clipChildren="false" sur la disposition parente.

0
Kavi

J'ai passé du temps à travailler dessus et j'ai finalement réalisé que lorsque le fond est sombre, l'ombre n'est pas visible 

0
Efi G