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:
J'ai également essayé ce qui suit en vain:
J'ai un peu joué avec les ombres sur Lollipop et voici ce que j'ai trouvé:
ViewGroup
coupent l'ombre de ses enfants pour une raison quelconque; etAndroid:elevation
sont coupées par les limites de la variable View
, et non par celles étendues dans la marge;Android:clipToPadding="false"
sur ce parent.Voici ma suggestion basée sur ce que je sais:
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;Android:clipToPadding="false"
sur la même RelativeLayout
;RelativeLayout
qui comporte également un ensemble d'altitude;À 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"
>
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.
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"
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.
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?
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>
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"
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"
/>
Parfois, comme background="@color/***"
ou background="#ff33**"
ne fonctionne pas, je remplace background_color
par drawable, alors cela fonctionne
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));
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"
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.
Si l'altitude ne s'affiche toujours pas, essayez
Android:hardwareAccelerated="true"
cela va certainement vous aider.
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.
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).
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" />
J'ai eu de la chance avec la définition de clipChildren="false"
sur la disposition parente.
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