Ombre de vue Android

102

J'ai cherché autour de moi et je n'ai pas trouvé de moyen approprié de le faire. Je souhaite avoir les effets d'ombre suivants sur mes vues: entrez la description de l'image ici

entrez la description de l'image ici

Pour être honnête, je ne sais pas si ce second se fait en appliquant un effet d'ombre. Des idées?

marcheur long
la source
1
Tu veux dire ça? stackoverflow.com/questions/4406524/… (cochez la réponse au vote le plus élevé, pas la réponse marquée)
Luke Vo
1
@DatVM, merci, cela semble faire l'affaire, mais je pensais qu'il existe peut-être des outils intégrés dans Android SDK. Par exemple, ajouter des ombres
portées
Question similaire - stackoverflow.com/q/52954743/9640177 - Ajout d'ombre au vecteur dessiné
mayank1513

Réponses:

158

Je sais que cette question a déjà reçu une réponse, mais je veux que vous sachiez que j'ai trouvé un drawablesur Android Studioqui est très similaire aux photos que vous avez dans la question: Jetez un œil à ceci:

android:background="@drawable/abc_menu_dropdown_panel_holo_light"

Cela ressemble à ceci:

entrez la description de l'image ici

J'espère que ce sera utile

Éditer

L'option ci-dessus concerne les anciennes versions de Android Studio, vous ne pourrez donc pas la trouver. Pour les versions plus récentes:

android:background="@android:drawable/dialog_holo_light_frame"

De plus, si vous souhaitez avoir votre propre forme personnalisée, je vous suggère d'utiliser un logiciel de dessin comme Photoshopet de le dessiner.

entrez la description de l'image ici

Ne pas oublier de l'enregistrer comme .9.pngfichier (exemple: my_background.9.png)

Lire la documentation: Draw 9-patch

Modifier 2

Une solution encore meilleure et moins efficace consiste à utiliser un CardViewensemble et app:cardPreventCornerOverlap="false"pour empêcher les vues de chevaucher les bordures:

<android.support.v7.widget.CardView
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardCornerRadius="2dp"
    app:cardElevation="2dp"
    app:cardPreventCornerOverlap="false"
    app:contentPadding="0dp">

    <!-- your layout stuff here -->

</android.support.v7.widget.CardView>

Assurez-vous également d'avoir inclus la dernière version dans le build.gradle,

compile 'com.android.support:cardview-v7:26.0.0'
Meule
la source
Merci, en fait, ça a l'air très similaire. J'ai aussi trouvé "google card layout" pour Android, et ils sont plutôt sympas!
longwalker
6
Impressionnant. Juste un FYI pour les futurs téléspectateurs, c'est en /<sdk-path>/extras/android/support.
theblang
2
Pourquoi ne pas utiliser uncardView
Alex Chengalan
100

J'utilise Android Studio 0.8.6 et je n'ai pas trouvé:

android:background="@drawable/abc_menu_dropdown_panel_holo_light"

donc j'ai trouvé ceci à la place:

android:background="@android:drawable/dialog_holo_light_frame"

et cela ressemble à ceci:

entrez la description de l'image ici

Repo
la source
1
mais on ne peut pas ajouter de rayon de coin avec ça?!
Fay007
40

mettre un arrière-plan de @android:drawable/dialog_holo_light_frame, donne une ombre mais vous ne pouvez pas changer la couleur d'arrière-plan ni le style de la bordure, il est donc préférable de profiter de l'ombre de celui-ci, tout en étant capable de mettre un arrière-plan via la liste des calques

<?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>

enregistrez-le dans le dossier dessinable sous dire shadow.xml

pour l'assigner à une vue, dans le fichier de mise en page xml définissez l'arrière-plan de celui-ci

android:background="@drawable/shadow"
Mohamed Selim
la source
Avez-vous vérifié si cela fonctionne? Le deuxième <item> ne fait rien. Je ne peux pas le changer en coins transparents ou arrondis.
zeeshan
2
Parmi tout ce que j'ai essayé, c'est la seule chose qui fonctionne, merci.
Shyam Sunder
1
fantastique solution
user1974368
34

Créez card_background.xml dans le dossier res / drawable avec le code suivant:

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

<item>
    <shape android:shape="rectangle">
        <solid android:color="#BDBDBD"/>
        <corners android:radius="5dp"/>
    </shape>
</item>

<item
    android:left="0dp"
    android:right="0dp"
    android:top="0dp"
    android:bottom="2dp">
    <shape android:shape="rectangle">
        <solid android:color="#ffffff"/>
        <corners android:radius="5dp"/>
    </shape>
</item>
</layer-list>

Ajoutez ensuite le code suivant à l'élément auquel vous voulez la mise en page de la carte

android:background="@drawable/card_background"

la ligne suivante définit la couleur de l'ombre de la carte

<solid android:color="#BDBDBD"/>
Vivek Varma
la source
10
Ce n'est pas vraiment une ombre - parce qu'elle ne s'estompe pas. C'est plus comme une bordure sur deux des côtés.
ban-geoengineering
ce n'est pas une ombre
ShadeToD
24

CardView vous donne une véritable ombre dans Android 5+ et dispose d'une bibliothèque de support. Enveloppez simplement votre vue et vous avez terminé.

<android.support.v7.widget.CardView>
     <MyLayout>
</android.support.v7.widget.CardView>

Il nécessite la prochaine dépendance.

dependencies {
    ...
    compile 'com.android.support:cardview-v7:21.0.+'
}
Ilya Gazman
la source
1
C'est la seule bonne réponse, car il n'y CardViewa que des niveaux d'ombre variables pour différentes élévations en mode compat.
Jarett Millard
Je recommande MaterialCardView car il est plus clair et a plus de capacités.
H. Farid le
12

C'est peut-être tard mais pour ceux qui recherchent encore une réponse, j'ai trouvé un projet sur git hub et c'est le seul qui correspond réellement à mes besoins. android-materialhadowninepatch

Ajoutez simplement cette ligne à votre dépendance build.gradle

compile 'com.h6ah4i.android.materialshadowninepatch:materialshadowninepatch:0.6.3'

à votre santé. bravo pour le créateur! happycodings

ralphgabb
la source
Hey @ralphgabb, est-ce que cela fonctionne toujours bien pour vous ou avez-vous une meilleure solution pour les appareils pré-sucette?
Swapnil le
@Swapnil ne sais pas si AndroidX prend en charge cela maintenant, je ne supporte plus les appareils pré-Marshmallow.
ralphgabb
5

Je sais que c'est stupidement hacky,
mais si vous voulez supporter sous v21, voici mes réalisations.

rectangle_with_10dp_radius_white_bg_and_shadow.xml

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

    <!-- Shadow layers -->
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_1" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_2" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_3" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_4" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_5" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_6" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_7" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_8" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_9" />
        </shape>
    </item>
    <item
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape>
            <corners android:radius="10dp" />
            <padding
                android:bottom="1.8dp"
                android:left="1dp"
                android:right="1dp"
                android:top="1dp" />
            <solid android:color="@color/shadow_hack_level_10" />
        </shape>
    </item>

    <!-- Background layer -->
    <item>
        <shape>
            <solid android:color="@android:color/white" />
            <corners android:radius="10dp" />
        </shape>
    </item>

</layer-list>

rectangle_with_10dp_radius_white_bg_and_shadow.xml (v21)

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@android:color/white" />
    <corners android:radius="10dp" />
</shape>

view_incoming.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:background="@drawable/rectangle_with_10dp_radius_white_bg_and_shadow"
    android:elevation="7dp"
    android:gravity="center"
    android:minWidth="240dp"
    android:minHeight="240dp"
    android:orientation="horizontal"
    android:padding="16dp"
    tools:targetApi="lollipop">

    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="Hello World !" />

</LinearLayout>

Voici le résultat:

Sous v21 (c'est ce que vous avez fait avec xml) entrez la description de l'image ici

Au-dessus de la v21 (rendu d'élévation réel) entrez la description de l'image ici

  • La seule différence significative est qu'il occupera l'espace intérieur de la vue, de sorte que votre zone de contenu réelle peut être plus petite que > = les appareils sucette .
wonsuc
la source
3

Si vous avez besoin que les ombres soient correctement appliquées, vous devez procéder comme suit.

Considérez cette vue, définie avec un arrière-plan dessinable:

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

L'arrière-plan dessinable est défini comme un rectangle aux coins arrondis:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="#42000000" />
    <corners android:radius="5dp" />
</shape>

C'est la façon recommandée d'apposer des ombres, vérifiez ceci https://developer.android.com/training/material/shadows-clipping.html#Shadows

Shangeeth Sivan
la source
2

Utilisez la propriété d'élévation pour l'effet d'ombre:

<YourView
    ...
    android:elevation="3dp"/>
Ofek Ashery
la source
L'utilisation de Elevation nécessite que l'appareil exécute Lollipop.
Shane Rowatt
2

Créez un arrière-plan dessinable comme celui-ci pour afficher une ombre arrondie.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Drop Shadow Stack -->
    <item>
        <shape>
            <corners android:radius="4dp" />
            <padding android:bottom="1dp" android:left="1dp"
                     android:right="1dp"  android:top="1dp" />
            <solid android:color="#00CCCCCC" />
        </shape>
    </item>
    <item>
        <shape>
            <corners android:radius="4dp" />
            <padding android:bottom="1dp" android:left="1dp"
                     android:right="1dp"  android:top="1dp" />
            <solid android:color="#10CCCCCC" />
        </shape>
    </item>
    <item>
        <shape>
            <corners android:radius="4dp" />
            <padding android:bottom="1dp" android:left="1dp"
                     android:right="1dp"  android:top="1dp" />
            <solid android:color="#20d5d5d5" />
        </shape>
    </item>
    <item>
        <shape>
            <corners android:radius="6dp" />
            <padding android:bottom="1dp" android:left="1dp"
                     android:right="1dp"  android:top="1dp" />
            <solid android:color="#30cbcbcb" />
        </shape>
    </item>
    <item>
        <shape>
            <corners android:radius="4dp" />
            <padding android:bottom="1dp" android:left="1dp"
                     android:right="1dp"  android:top="1dp" />
            <solid android:color="#50bababa" />
        </shape>
    </item>

    <!-- Background -->
    <item>
        <shape>
            <solid android:color="@color/gray_100" />
            <corners android:radius="4dp" />
        </shape>
    </item>
</layer-list>
gaurav iqlance
la source
Veuillez également ajouter une description pour le code que vous avez fourni.
Mangaldeep Pannu
Très belle solution xml uniquement
Bruno Bieri
2

Cette question est peut-être ancienne, mais pour quiconque souhaite à l'avenir 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 couleur".

BluRe.CN
la source
1

utilisez cette forme comme arrière-plan:

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

    <item android:drawable="@android:drawable/dialog_holo_light_frame"/>

    <item>
        <shape android:shape="rectangle">
            <corners android:radius="1dp" />
            <solid android:color="@color/gray_200" />
        </shape>
    </item>

</layer-list>
Monsieur Hosseini
la source