web-dev-qa-db-fra.com

Ajouter une ombre à une forme personnalisée sur Android

Est-il possible d'ajouter une ombre portée à une forme personnalisée dans Android? Après avoir parcouru la documentation, je ne vois qu'un moyen d'appliquer une ombre de texte.

J'ai essayé sans succès:

<?xml version="1.0" encoding="UTF-8"?> 
   <shape xmlns:Android="http://schemas.Android.com/apk/res/Android" 
   Android:shape="rectangle"> 
     <solid Android:color="#90ffffff"/>
       <corners Android:radius="12dp" />
     <item name="Android:shadowColor">#000000</item> 
     <item name="Android:shadowRadius">5</item> 
     <item name="Android:shadowDy">3</item> 
   </shape>
105
mdunkle

Après beaucoup de recherches, finalement j'ai eu ceci 

enter image description here

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">

<!-- Bottom 2dp Shadow -->
<item>
    <shape  Android:shape="rectangle">

        <solid Android:color="#d8d8d8" />
        <corners Android:radius="7dp" />

    </shape>
</item>

<!-- White Top color -->
<item Android:bottom="3px">

    <shape  Android:shape="rectangle">

    <solid Android:color="#FFFFFF" />
    <corners Android:radius="7dp" />


    </shape>

</item>


</layer-list>
142
Chirag Patel

Voici comment je le fais:

Android Native Button with Shadows

Code ci-dessous pour un bouton STATE:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >
    <!-- "background shadow" -->
    <item>
        <shape Android:shape="rectangle" >
            <solid Android:color="#000000" />

            <corners Android:radius="15dp" />
        </shape>
    </item>
    <!-- background color -->
    <item
        Android:bottom="3px"
        Android:left="3px"
        Android:right="3px"
        Android:top="3px">
        <shape Android:shape="rectangle" >
            <solid Android:color="#cc2b2b" />


            <corners Android:radius="8dp" />
        </shape>
    </item>
    <!-- over left shadow -->
    <item>
        <shape Android:shape="rectangle" >
            <gradient
                Android:angle="180"
                Android:centerColor="#00FF0000"
                Android:centerX="0.9"
                Android:endColor="#99000000"
                Android:startColor="#00FF0000" />

            <corners Android:radius="8dp" />
        </shape>
    </item>
    <!-- over right shadow -->
    <item>
        <shape Android:shape="rectangle" >
            <gradient
                Android:angle="360"
                Android:centerColor="#00FF0000"
                Android:centerX="0.9"
                Android:endColor="#99000000"
                Android:startColor="#00FF0000" />

            <corners Android:radius="8dp" />
        </shape>
    </item>
    <!-- over top shadow -->
    <item>
        <shape Android:shape="rectangle" >
            <gradient
                Android:angle="-90"
                Android:centerColor="#00FF0000"
                Android:centerY="0.9"
                Android:endColor="#00FF0000"
                Android:startColor="#99000000"
                Android:type="linear" />

            <corners Android:radius="8dp" />
        </shape>
    </item>
    <!-- over bottom shadow -->
    <item>
        <shape Android:shape="rectangle" >
            <gradient
                Android:angle="90"
                Android:centerColor="#00FF0000"
                Android:centerY="0.9"
                Android:endColor="#00FF0000"
                Android:startColor="#99000000"
                Android:type="linear" />

            <corners Android:radius="8dp" />
        </shape>
    </item>
</layer-list>

Ensuite, vous devriez avoir un sélecteur avec différentes versions du bouton, quelque chose comme:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <item Android:drawable="@drawable/ic_button_red_pressed" Android:state_pressed="true"/> <!-- pressed -->
    <item Android:drawable="@drawable/ic_button_red_selected" Android:state_focused="true"/> <!-- focused -->
    <item Android:drawable="@drawable/ic_button_red_selected" Android:state_selected="true"/> <!-- selected -->
    <item Android:drawable="@drawable/ic_button_red_default"/> <!-- default -->

</selector>

espérons que cela peut vous aider .. bonne chance

72
João Machete

Ceci est ma version d'une ombre portée. Je cherchais une ombre floue autour de la forme et utilisais cette réponse de Joakim Lundborg comme point de départ. Ce que j’ai changé, c’est d’ajouter des coins à tous les éléments de l’ombre et d’augmenter le rayon de chaque angle. Alors voici la xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <!-- Drop Shadow Stack -->
    <item>
        <shape>
            <padding Android:top="1dp" Android:right="1dp" Android:bottom="1dp" Android:left="1dp" />
            <solid Android:color="#02000000" />
            <corners Android:radius="8dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding Android:top="1dp" Android:right="1dp" Android:bottom="1dp" Android:left="1dp" />
            <solid Android:color="#05000000" />
            <corners Android:radius="7dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding Android:top="1dp" Android:right="1dp" Android:bottom="1dp" Android:left="1dp" />
            <solid Android:color="#10000000" />
            <corners Android:radius="6dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding Android:top="1dp" Android:right="1dp" Android:bottom="1dp" Android:left="1dp" />
            <solid Android:color="#15000000" />
            <corners Android:radius="5dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding Android:top="1dp" Android:right="1dp" Android:bottom="1dp" Android:left="1dp" />
            <solid Android:color="#20000000" />
            <corners Android:radius="4dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding Android:top="1dp" Android:right="1dp" Android:bottom="1dp" Android:left="1dp" />
            <solid Android:color="#25000000" />
            <corners Android:radius="3dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding Android:top="1dp" Android:right="1dp" Android:bottom="1dp" Android:left="1dp" />
            <solid Android:color="#30000000" />
            <corners Android:radius="3dp" />
        </shape>
    </item>

    <!-- Background -->
    <item>
    <shape>
            <solid Android:color="#0099CC" />
        <corners Android:radius="3dp" />
    </shape>
   </item>
</layer-list>
41
BruceHill

Ce qui suit a fonctionné pour moi: il suffit de sauvegarder sous custom_shape.xml.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android" >

    <!-- "shadow" -->
    <item>
        <shape Android:shape="rectangle" >
           <solid Android:color="#000000"/>
           <corners Android:radius="12dp" />
        </shape>
    </item>


    <item Android:bottom="3px">
        <shape Android:shape="rectangle"> 
            <solid Android:color="#90ffffff"/>
            <corners Android:radius="12dp" />
         </shape>
    </item>

</layer-list>
28
Siklab.ph

Je pense que cette méthode donne de très bons résultats:

<!-- Drop Shadow Stack -->
<item>
    <shape>
        <padding
                Android:top="1dp"
                Android:right="1dp"
                Android:bottom="1dp"
                Android:left="1dp"/>
        <solid Android:color="#00CCCCCC"/>
    </shape>
</item>
<item>
    <shape>
        <padding
                Android:top="1dp"
                Android:right="1dp"
                Android:bottom="1dp"
                Android:left="1dp"/>
        <solid Android:color="#10CCCCCC"/>
    </shape>
</item>
<item>
    <shape>
        <padding
                Android:top="1dp"
                Android:right="1dp"
                Android:bottom="1dp"
                Android:left="1dp"/>
        <solid Android:color="#20CCCCCC"/>
    </shape>
</item>
<item>
    <shape>
        <padding
                Android:top="1dp"
                Android:right="1dp"
                Android:bottom="1dp"
                Android:left="1dp"/>
        <solid Android:color="#30CCCCCC"/>
    </shape>
</item>
<item>
    <shape>
        <padding
                Android:top="1dp"
                Android:right="1dp"
                Android:bottom="1dp"
                Android:left="1dp"/>
        <solid Android:color="#50CCCCCC"/>
    </shape>
</item>

<item>

    <shape Android:shape="rectangle">
        <stroke Android:color="#CCC" Android:width="1dp"/>
        <solid Android:color="#FFF" />
        <corners Android:radius="2dp" />

    </shape>

</item>

J'ai trouvé ceci à: http://www.uifuel.com/Android-creating-a-dd-shadow-in-xml-layout/

26
Joakim Lundborg

Si cela ne vous dérange pas de faire un dessin personnalisé avec l'API Canvas, consultez cette réponse à propos de drop shadows . Voici un suivi question à celle qui résout un problème dans l'original.

7
Josh

Ancienne question, mais Elevation, disponible avec Material Design, fournit désormais une ombre à toutes les vues.

<TextView
Android:id="@+id/myview"
...
Android:elevation="2dp"
Android:background="@drawable/myrect" />

Voir la documentation à https://developer.Android.com/training/material/shadows-clipping.html

5
wainy

Je pense que cette valeur d'ombre portée est bonne dans la plupart des cas:

<solid Android:color="#20000000" />
2
user1238561

enter image description here

  <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:Android="http://schemas.Android.com/apk/res/Android" >

        <solid Android:color="@Android:color/white" >
        </solid>

        <stroke
            Android:width="1dp"
            Android:color="@color/LightGrey" >
        </stroke>

        <padding
            Android:bottom="5dp"
            Android:left="2dp"
            Android:right="2dp"
            Android:top="5dp" >
        </padding>

        <corners
            Android:bottomLeftRadius="20dp"
            Android:bottomRightRadius="20dp"
            Android:radius="12dp"
            Android:topLeftRadius="20dp"
            Android:topRightRadius="20dp" />

        <gradient
            Android:angle="90"
            Android:centerColor="@Android:color/white"
            Android:centerY="0.2"
            Android:endColor="#99e0e0e0"
            Android:startColor="@Android:color/white"
            Android:type="linear" />

    </shape>
2
Gdroid

Cette question est peut-être ancienne, mais pour quiconque à l'avenir voudra un moyen simple d'obtenir des effets d'ombre complexes, consultez ma bibliothèque ici https://github.com/BluRe-CN/ComplexView

En utilisant la bibliothèque, vous pouvez modifier les couleurs des ombres, ajuster les bords et bien plus encore. Voici un exemple pour réaliser ce que vous recherchez.

<com.blure.complexview.ComplexView
        Android:layout_width="400dp"
        Android:layout_height="600dp"
        app:radius="10dp"
        app:shadow="true"
        app:shadowSpread="2">

        <com.blure.complexview.ComplexView
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            app:color="#fdfcfc"
            app:radius="10dp" />
    </com.blure.complexview.ComplexView>

Pour changer la couleur de l'ombre, utilisez app: shadowColor = "votre code de couleur".

1
BluRe.CN

Je suggérerais une légère amélioration par rapport à la solution de Bruce, qui consiste à éviter de superposer la même forme l'un sur l'autre et à utiliser simplement un trait au lieu de trait plein… .. Cela ressemblerait à ceci:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <!-- Drop Shadow Stack -->
    <item>
        <shape>
            <padding Android:top="1dp" Android:right="1dp" Android:bottom="1dp" Android:left="1dp" />
            <stroke Android:color="#02000000" Android:width="1dp"  />
            <corners Android:radius="8dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding Android:top="1dp" Android:right="1dp" Android:bottom="1dp" Android:left="1dp" />
            <stroke Android:color="#05000000" Android:width="1dp" />
            <corners Android:radius="7dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding Android:top="1dp" Android:right="1dp" Android:bottom="1dp" Android:left="1dp" />
            <stroke Android:color="#10000000" Android:width="1dp" />
            <corners Android:radius="6dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding Android:top="1dp" Android:right="1dp" Android:bottom="1dp" Android:left="1dp" />
            <stroke Android:color="#15000000" Android:width="1dp" />
            <corners Android:radius="5dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding Android:top="1dp" Android:right="1dp" Android:bottom="1dp" Android:left="1dp" />
            <stroke Android:color="#20000000" Android:width="1dp" />
            <corners Android:radius="4dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding Android:top="1dp" Android:right="1dp" Android:bottom="1dp" Android:left="1dp" />
            <stroke Android:color="#25000000" Android:width="1dp" />
            <corners Android:radius="3dp" />
        </shape>
    </item>
    <item>
        <shape>
            <padding Android:top="1dp" Android:right="1dp" Android:bottom="1dp" Android:left="1dp" />
            <stroke Android:color="#30000000" Android:width="1dp" />
            <corners Android:radius="3dp" />
        </shape>
    </item>

    <!-- Background -->
    <item>
        <shape>
            <solid Android:color="#FFF" />
            <corners Android:radius="3dp" />
        </shape>
    </item>
</layer-list>

 screenshot of the rendering of the shadow Enfin, je voulais signaler aux personnes qui souhaitent une ombre dans une direction spécifique que tout ce que vous avez à faire est de régler le haut, le bas, la gauche ou la droite sur 0dp (pour une ligne continue) ou -1dp ( pour rien)

0
Francois Dermu

si vous avez besoin d'une ombre en ligne droite (comme en bas de la barre d'outils), vous pouvez également utiliser un dégradé xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <gradient
        Android:type="linear"
        Android:angle="-90"
        Android:startColor="#19000000" <!-- black transparent -->
        Android:endColor="#00000000" /> <!-- full transparent -->
</shape>

espérons que cela aidera quelqu'un

0
Saeed Arianmanesh