Dans les exemples Android 5.0 du gestionnaire de SDK, il existe l'exemple ElevationBasic
. Il montre deux objets View
: un cercle et un carré. Le cercle a Android:elevation
défini sur 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>
Sur un Nexus 9, exécutant l'échantillon tel quel, nous obtenons une ombre portée sur le cercle:
Si nous modifions la classe de widget en Button
, en laissant tous les autres attributs tels quels, nous perdons l'ombre portée du cercle:
Questions:
Pourquoi le comportement Android:elevation
est-il en train de changer? Cela ne peut pas être dû au fond, car c'est le même fond dans les deux cas.
Quelles classes supportent Android:elevation
et lesquelles ne le font pas? Par exemple, utiliser TextView
au lieu de View
ou Button
nous donne toujours l'ombre portée. Ce changement de comportement n'est donc pas introduit au niveau TextView
, mais au niveau Button
.
Comme on le voit dans cette question d’hier, comment pouvons-nous obtenir que Android:elevation
soit honoré sur une Button
? Y at-il une valeur Android:allowElevationToWorkAsDocumented="true"
que nous devons mettre dans un thème ou quelque chose?
Le style de bouton par défaut sous Material a un StateListAnimator qui contrôle les propriétés Android:elevation
et Android:translationZ
. Vous pouvez supprimer l'animateur existant ou définir le vôtre à l'aide de la propriété Android:stateListAnimator
.
<Button
...
Android:stateListAnimator="@null" />
<Button
...
Android:stateListAnimator="@anim/my_animator" />
L'animateur par défaut est défini dans button_state_list_anim_material.xml . Voici un exemple montrant les états activé et activé:
<?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>
D'après mon expérience d'Appcompat v7 s'exécutant sur un périphérique Lollipop, Button
fonctionne avec les fonctionnalités par défaut telles que l'effet d'entraînement, l'élévation et l'animation z au clic, mais les omet si une propriété Android:background
personnalisée (comme couleur ou sélecteur) est définie dans l'élément xml.
En effet, vous définissez manuellement l’arrière-plan du bouton qui remplacera tous ses effets.
A partir de la version 23.0.0 release de AppCompat , il existe un nouveau style Widget.AppCompat.Button.Colored qui utilise le colorButtonNormal de votre thème pour la couleur désactivée et colorAccent pour la couleur activée .
<Button
...
style="@style/Widget.AppCompat.Button.Colored" />
Si vous voulez des couleurs différentes de celles spécifiées, vous pouvez créer un nouveau thème et l’appliquer au bouton via Android:theme
. Ensuite, vous pouvez utiliser ce thème sur tous vos boutons où vous voulez le même effet.
Je pensais que le problème était dû à une mise en page mal gonflée, mais il est apparu que l'ajout de clipToPadding
permettait de résoudre le problème . Ce paramètre devait être défini sur le parent ViewGroup
contenant la vue sur laquelle vous souhaitez créer une ombre.
...
Android:clipToPadding="false"
...
Cette solution fonctionne pour toutes les versions d'API d'Android.
Créez une ombre @Android:drawable/dialog_holo_light_frame
& si vous souhaitez personnaliser la couleur de l'arrière-plan plutôt que le blanc, créez un arrière-plan de liste de calques avec une couleur personnalisable au-dessus de l'ombre, comme indiqué ci-dessous.
Créer un fichier dessinable séparé 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>
et utiliser ce dessin comme arrière-plan comme celui-ci
Android:background="@drawable/shadow"