La "elevación" de Android no muestra una sombra
Tengo un ListView y con cada elemento de la lista quiero que muestre una sombra debajo. Estoy usando la nueva función de elevación de Android Lollipop para establecer una Z en la Vista en la que quiero proyectar una sombra, y ya lo estoy haciendo de manera efectiva con ActionBar (técnicamente, una barra de herramientas en Lollipop). Estoy usando la elevación de Lollipop, pero por alguna razón no muestra una sombra debajo de los elementos de la lista. Así es como se configura el diseño de cada elemento de la lista:
<?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>
Sin embargo, así es como se muestra el elemento de la lista, sin sombra:
También intenté lo siguiente sin éxito:
- Establezca la elevación en ImageView y TextView en lugar del diseño principal.
- Se aplicó un fondo a ImageView.
- Usé TranslationZ en lugar de Elevation.
He estado jugando un poco con las sombras en Lollipop y esto es lo que encontré:
- Parece que
ViewGroup
los límites de un padre cortan la sombra de sus hijos por alguna razón; y - las sombras establecidas con
android:elevation
están cortadas por losView
límites de ', no por los límites extendidos a través del margen; - la forma correcta de hacer que una vista secundaria muestre sombra es configurar el relleno en el padre y establecerlo
android:clipToPadding="false"
en ese padre.
Aquí está mi sugerencia basada en lo que sé:
- Configure su nivel superior
RelativeLayout
para que tenga un relleno igual a los márgenes que estableció en el diseño relativo en el que desea mostrar la sombra; - puesto
android:clipToPadding="false"
en el mismoRelativeLayout
; - Elimine el margen del
RelativeLayout
que también tiene establecida la elevación; - [EDITAR] es posible que también necesite establecer un color de fondo no transparente en el diseño secundario que necesita elevación.
Al final del día, su diseño relativo de nivel superior debería verse así:
<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"
>
El diseño relativo interior debería verse así:
<RelativeLayout
android:layout_width="300dp"
android:layout_height="300dp"
android:background="[some non-transparent color]"
android:elevation="30dp"
>
Si tienes una vista sin fondo esta línea te ayudará
android:outlineProvider="bounds"
De forma predeterminada, la sombra está determinada por el fondo de la vista, por lo que si no hay fondo, tampoco habrá sombra.
Aparentemente, no se puede simplemente establecer una elevación en una Vista y hacer que aparezca. También debe especificar un fondo.
Las siguientes líneas agregadas a mi LinearLayout finalmente mostraron una sombra:
android:background="@android:color/white"
android:elevation="10dp"
Otra cosa que debes tener en cuenta es que las sombras no se mostrarán si tienes esta línea en el manifiesto:
android:hardwareAccelerated="falso"
Probé todas las cosas sugeridas pero solo funcionó cuando eliminé la línea, la razón por la que tenía la línea fue porque mi aplicación funciona con varias imágenes de mapa de bits y estaban provocando que la aplicación fallara.
Si tienes una vista sin fondo esta línea te ayudará
android:outlineProvider="bounds"
Si tienes una vista con fondo esta línea te ayudará
android:outlineProvider="paddedBounds"