kitkat - android lollipop descargar
Android 5.0 android: la elevación funciona para la vista, ¿pero no para el botón? (5)
El estilo de botón predeterminado en Material tiene un
StateListAnimator
que controla las propiedades
android:elevation
y
android:translationZ
.
Puede eliminar el animador existente o configurar el suyo usando la propiedad
android:stateListAnimator
.
<Button
...
android:stateListAnimator="@null" />
<Button
...
android:stateListAnimator="@anim/my_animator" />
El animador predeterminado se define en button_state_list_anim_material.xml . Aquí hay una muestra que muestra los estados habilitado y presionado:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:state_enabled="true">
<set>
<objectAnimator android:propertyName="translationZ"
android:duration="@integer/button_pressed_animation_duration"
android:valueTo="@dimen/button_pressed_z_material"
android:valueType="floatType"/>
<objectAnimator android:propertyName="elevation"
android:duration="0"
android:valueTo="@dimen/button_elevation_material"
android:valueType="floatType"/>
</set>
</item>
<!-- base state -->
<item android:state_enabled="true">
<set>
<objectAnimator android:propertyName="translationZ"
android:duration="@integer/button_pressed_animation_duration"
android:valueTo="0"
android:startDelay="@integer/button_pressed_animation_delay"
android:valueType="floatType"/>
<objectAnimator android:propertyName="elevation"
android:duration="0"
android:valueTo="@dimen/button_elevation_material"
android:valueType="floatType" />
</set>
</item>
...
</selector>
En las muestras de Android 5.0 del SDK Manager, está la muestra de
ElevationBasic
.
Muestra dos objetos de
View
: un círculo y un cuadrado.
El círculo tiene
android:elevation
establecida en
30dp
:
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="@+id/floating_shape"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginRight="40dp"
android:background="@drawable/shape"
android:elevation="30dp"
android:layout_gravity="center"/>
<View
android:id="@+id/floating_shape_2"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginLeft="25dp"
android:background="@drawable/shape2"
android:layout_gravity="center"/>
</FrameLayout>
En un Nexus 9, ejecutando la muestra tal cual, obtenemos una sombra paralela en el círculo:
Si cambiamos la clase de widget a
Button
, dejando todos los demás atributos tal como están, perdemos la sombra del círculo:
Las preguntas:
-
¿Por qué cambia el comportamiento de
android:elevation
? No puede ser debido al fondo, porque es el mismo fondo en ambos casos. -
¿Qué clases admiten
android:elevation
y cuáles no? Por ejemplo, usarTextView
lugar deView
oButton
todavía nos da la sombra, por lo que este cambio de comportamiento no se introduce en el nivelTextView
, sino en el nivelButton
. -
Como se vio en esta pregunta de ayer, ¿cómo obtenemos
android:elevation
para ser honrado en unButton
? ¿Hay algún valor deandroid:allowElevationToWorkAsDocumented="true"
que tenemos que poner en un tema o algo así?
En mi experiencia con Appcompat v7 que se ejecuta en el dispositivo Lollipop,
Button
funciona con funciones predeterminadas como efecto dominó, elevación y animación z al hacer clic, pero las pierde si se configura una propiedad de
android:background
personalizada de
android:background
(como color o selector) en el elemento xml.
Esta solución funciona para todas las versiones API de Android
Cree una sombra
@android:drawable/dialog_holo_light_frame
y, si desea personalizar el color del fondo en lugar del blanco, cree un fondo de lista de capas con un color personalizable en la parte superior de la sombra como se muestra a continuación
Cree un archivo dibujable por separado white_background_shadow.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!--the shadow comes from here-->
<item
android:bottom="0dp"
android:drawable="@android:drawable/dialog_holo_light_frame"
android:left="0dp"
android:right="0dp"
android:top="0dp">
</item>
<item
android:bottom="0dp"
android:left="0dp"
android:right="0dp"
android:top="0dp">
<!--whatever you want in the background, here i preferred solid white -->
<shape android:shape="rectangle">
<solid android:color="@android:color/white" />
</shape>
</item>
</layer-list>
y usa este dibujo como fondo como este
android:background="@drawable/shadow"
Esto se debe a que está configurando el fondo del botón manualmente, lo que reemplazará todos sus efectos.
A partir de la versión 23.0.0 de AppCompat , hay un nuevo estilo Widget.AppCompat.Button.Colored que utiliza el colorButtonNormal de su tema para el color deshabilitado y colorAccent para el color habilitado.
<Button
...
style="@style/Widget.AppCompat.Button.Colored" />
Si desea colores diferentes a los especificados, puede crear un nuevo tema y aplicarlo al botón a través de
android:theme
.
Luego puede usar este tema en todos sus botones donde desee el mismo efecto.
Tuve un problema similar que pensé que se debía a diseños inflados incorrectamente, pero parecía que agregar
clipToPadding
fue el truco.
Esto debe establecerse en el
ViewGroup
primario que contiene la vista que desea proyectar una sombra.
... android:clipToPadding="false" ...