studio - Android "elevación" no muestra una sombra
android shape shadow (16)
Tengo un ListView, y con cada elemento de la lista quiero que muestre una sombra debajo de él. Estoy usando la nueva función de elevación de Android Lollipop para establecer una Z en la Vista que quiero proyectar una sombra, y ya lo estoy haciendo de manera efectiva con la Barra de Acción (técnicamente una Barra de Herramientas en Lollipop). Estoy utilizando la elevación de Lollipop, pero por alguna razón no muestra una sombra debajo de los elementos de la lista. Aquí es cómo 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, aquí está cómo muestra el elemento de la lista, sin una sombra:
También he intentado lo siguiente en vano:
- Establezca la elevación en ImageView y TextViews en lugar del diseño principal.
- Se aplicó un fondo a la ImageView.
- TranslationZ usado en lugar de elevación.
Además de la respuesta aceptada, hay una razón más por la cual la elevación puede no funcionar como se espera.
Si la función de filtro de Bluelight en el teléfono está activada
Estaba enfrentando este problema cuando la elevación parecía completamente distorsionada e insoportable en mi dispositivo. Pero la elevación estaba bien en la vista previa. Apagar el filtro de Bluelight en el teléfono resolvió el problema.
Así que incluso después de configurar
android:outlineProvider="bounds"
La elevación no funciona correctamente, entonces puede intentar modificar la configuración de color del teléfono.
Agregar color de fondo me ayudó.
<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"
/>
Aparentemente, no puedes simplemente establecer una elevación en una Vista y hacer que aparezca. También es necesario especificar un fondo.
Las siguientes líneas agregadas a mi LinearLayout finalmente mostraron una sombra:
android:background="@android:color/white"
android:elevation="10dp"
Creo que su problema se deriva del hecho de que ha aplicado el elemento de elevación a un diseño relativo que llena su elemento primario. Su padre recorta todas las vistas secundarias dentro de su propio lienzo de dibujo (y es la vista que maneja la sombra del niño). Puede corregir esto aplicando una propiedad de elevación al RelativeLayout
superior en su xml de vista (la etiqueta raíz).
Dale un poco de color de fondo al diseño trabajado para mí como:
android:background="@color/catskill_white"
android:layout_height="?attr/actionBarSize"
android:elevation="@dimen/dimen_5dp"
En mi caso las fuentes fueron el problema.
1) Sin fontFamily
necesitaba establecer android:background
a algún valor.
<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) con fontFamily
tuve que agregar la 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" />
He estado jugando con sombras en Lollipop por un tiempo y esto es lo que he encontrado:
- Parece que los límites de un grupo principal de
ViewGroup
la sombra de sus hijos por alguna razón; y - sombras establecidas con
android:elevation
está cortada por los límites de laView
, no los límites extendidos a través del margen; - La forma correcta de obtener una vista secundaria para mostrar la sombra es establecer el relleno en el padre y establecer
android:clipToPadding="false"
en ese padre.
Aquí está mi sugerencia basada en lo que sé:
- Configure su
RelativeLayout
nivel superior para tener un relleno igual a los márgenes que ha establecido en el diseño relativo que desea mostrar sombra; - set
android:clipToPadding="false"
en el mismoRelativeLayout
; - Elimine el margen del
RelativeLayout
que también tiene un conjunto de elevación; - [EDITAR] es posible que también deba 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 debe tener este aspecto:
<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 debe verse así:
<RelativeLayout
android:layout_width="300dp"
android:layout_height="300dp"
android:background="[some non-transparent color]"
android:elevation="30dp"
>
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 = "false"
Intenté todas las cosas sugeridas, pero solo funcionó para mí cuando quité la línea, la razón por la que tenía la línea era porque mi aplicación funciona con varias imágenes de mapa de bits y causaban que la aplicación fallara.
Pasé un tiempo trabajando en ello y finalmente me di cuenta de que cuando el fondo está oscuro, la sombra no es visible.
Si desea tener un fondo transparente y android:outlineProvider="bounds"
no funciona para usted, puede crear ViewOutlineProvider personalizado:
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);
}
}
Y establezca este proveedor a su vista transparente:
transparentView.setOutlineProvider(new TransparentOutlineProvider());
Fuentes: https://code.google.com/p/android/issues/detail?id=78248#c13
[EDITAR] La documentación de Drawable.getAlpha () dice que es específica a cómo el Drawable amenaza al alfa. Es posible que siempre devuelva 255. En este caso, puede proporcionar el alfa manualmente:
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 el fondo de la vista es un StateListDrawable con el color predeterminado # DDFF0000 que es con alfa DDx0 / FFx0 == 0.86
transparentView.setOutlineProvider(new TransparentOutlineProvider(0.86f));
Si está agregando una elevación a un elemento de botón, necesita agregar la siguiente línea:
android:stateListAnimator="@null"
Ver Android 5.0 android: elevation Works for View, pero no Button?
Si tiene una vista sin fondo esta línea le ayudará
android:outlineProvider="bounds"
Por defecto, la sombra está determinada por el fondo de la vista, por lo que si no hay fondo, tampoco habrá sombra.
Si tiene una vista sin fondo esta línea le ayudará
android:outlineProvider="bounds"
Si tienes una vista con fondo esta línea te ayudará
android:outlineProvider="paddedBounds"
Tuve algo de suerte con la configuración de clipChildren="false"
en el diseño principal.
Ugh, acabo de pasar una hora tratando de resolver esto. En mi caso tenía un conjunto de fondo, sin embargo, se estableció en un color. Esto no es suficiente, debe tener el fondo de la vista establecido en un dibujable.
Por ejemplo, esto no tendrá una sombra:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="165dp"
android:background="@color/ight_grey"
android:elevation="20dp"
android:orientation="vertical"
/>
pero esta voluntad
<LinearLayout
android:layout_width="match_parent"
android:layout_height="165dp"
android:background="@drawable/selector_grey"
android:elevation="20dp"
android:orientation="vertical"
/>
EDITAR: También descubrí que si usa un selector como fondo, si no tiene la esquina configurada, entonces la sombra no aparecerá en la ventana de Vista previa, pero aparecerá en el dispositivo
Por ejemplo, esto no tiene una sombra en la vista previa:
<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>
pero esto hace:
<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>
a veces, como background = "@ color / *" o background = "# ff33 " no funciona, sustituyo background_color por drawable, luego funciona