Android LinearLayout: ajouter une bordure avec une ombre autour d'un LinearLayout

147

Je voudrais créer la même bordure de ce LinearLayout que l'exemple:

entrez la description de l'image ici

Dans cet exemple, nous pouvons voir que la bordure n'est pas la même tout autour du linearLayout. Comment puis-je créer cela à l'aide d'un fichier XML dessinable?

Pour l'instant, je n'ai pu créer qu'une simple bordure tout autour du LinearLayout comme ceci:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
  <corners
      android:radius="1dp"
      android:topRightRadius="0dp"
      android:bottomRightRadius="0dp"
      android:bottomLeftRadius="0dp" />
  <stroke
      android:width="1dp"
      android:color="#E3E3E1" />

  <solid android:color="@color/blanc" />

</shape>
Wawanopoulos
la source
1
vous pouvez utiliser la backgroundpropriété pour cela ... créer un fichier XML avec une forme comme un rectangle, une couleur et un effet d'ombre et le définir comme arrière-plan pour votre mise en page linéaire ..
Pragnesh Ghoda シ
utiliser le trait pour la bordure grise et l'effet de rembourrage aussi
Pragnesh Ghoda シ
Je pense que ses deux mises en page xml, disons que l'une est une mise en page linéaire et que l'intérieur est une mise en page relative avec un rembourrage
Giru Bhai
@ Prag's Pourriez-vous m'aider pour créer ce fichier xml s'il vous plaît?
wawanopoulos
1
Une autre manière pourrait être d'utiliser une image de patch 9 comme arrière-plan de votre mise en page. Cela permettrait une ombre vraiment douce et décolorée (très réaliste, à mon avis).
Phantômaxx

Réponses:

257

Essaye ça..

<?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="#CABBBBBB"/>
            <corners android:radius="2dp" />
        </shape>
    </item>

    <item
        android:left="0dp"
        android:right="0dp"
        android:top="0dp"
        android:bottom="2dp">
        <shape android:shape="rectangle">
            <solid android:color="@android:color/white"/>
            <corners android:radius="2dp" />
        </shape>
    </item>
</layer-list>
Hariharan
la source
@Hariharan Merci beaucoup! J'ai essayé votre code et cela semble correct. Mais, il y a encore une chose à faire, comment puis-je ajouter une fine bordure (1dp) à gauche et à droite de la disposition linéaire? (à titre d'exemple)
wawanopoulos
2
@wawanopoulos Remplacez simplement "0dp"par "1dp"dans la réponse d'Hariharan.
Phantômaxx
vous pouvez ajouter la couleur #EAEAEA à la mise en page parent afin que ce soit exactement comme l'image de la question
Samad
3
Je suggérerais également pour cela, que vous puissiez utiliser <gradient>dans votre <shape>pour améliorer l'effet de bordure, et aussi si c'est vraiment l'effet dont votre interface utilisateur a besoin au lieu d'une simple bordure de couleur unie.
patrickjason91
assurez-vous que si vous avez une mise en page interne avec match_parent, donnez la marge 1 à la mise en page interne
Shaktisinh Jadeja
82

C'est pourquoi CardView existe. CardView | Développeurs Android
C'est juste un FrameLayout qui prend en charge l'élévation dans les appareils pré-sucette.

<android.support.v7.widget.CardView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:cardUseCompatPadding="true"
    app:cardElevation="4dp"
    app:cardCornerRadius="3dp" >

    <!-- put whatever you want -->

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

Pour l'utiliser, vous devez ajouter une dépendance à build.gradle:

compile 'com.android.support:cardview-v7:23.+'
Ray Suhyun Lee
la source
comment changer la couleur de l'ombre
Aditay Kaushal
l'ombre est très faible stackoverflow.com/questions/49076188/…
user924
1
comportement très étrange dans les appareils avec 4.4.4 (ou similaire). Une énorme marge est ajoutée à la vue de la carte et rend l'interface utilisateur très moche.
Morteza Rastgoo
Cela devrait être la réponse acceptée. Une petite mise à jour cependant. Vous devriez utiliser le androidx one -> androidx.cardview.widget.CardView
bogdan
59

J'obtiens les meilleurs résultats en utilisant un graphique 9 patch.

Vous pouvez simplement créer un graphique de patch 9 individuel en utilisant l'éditeur suivant: http://inloop.github.io/shadow4android/

Exemple:

Le graphique 9 patch:

Le graphique 9 patch:

Le résultat:

entrez la description de l'image ici

La source:

<LinearLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:orientation="vertical"
android:background="@drawable/my_nine_patch"
funcoder
la source
1
Comment puis-je masquer la ligne noire? S'il vous plaît aider
Isaac Darlong
@Isaac enregistrer l'image comme my_nine_patch.9.png (.9.png est 9 image en lots)
arun
C'EST LE MEILLEUR!
Numanqmr
35

ok, je sais que c'est trop tard. mais j'avais la même exigence. j'ai résolu comme ça

1. Commencez par créer un fichier xml (exemple: border_shadow.xml) dans le dossier "drawable" et copiez-y le code ci-dessous.

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

<item>
    <shape>
        <!-- set the shadow color here -->
        <stroke
            android:width="2dp"
            android:color="#7000" />

        <!-- setting the thickness of shadow (positive value will give shadow on that side) -->

        <padding
            android:bottom="2dp"
            android:left="2dp"
            android:right="-1dp"
            android:top="-1dp" />

        <corners android:radius="3dp" />
    </shape>
</item>

<!-- Background -->

<item>
    <shape>
        <solid android:color="#fff" />
        <corners android:radius="3dp" />
    </shape>
</item>

2. maintenant sur la mise en page où vous voulez l'ombre (exemple: LinearLayout) ajoutez ceci dans android: background

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dip"
    android:background="@drawable/border_shadow"
    android:orientation="vertical">

et cela a fonctionné pour moi.

user3619170
la source
21

C'est si simple:

Créez un fichier dessinable avec un dégradé comme celui-ci:

pour l'ombre sous une vue below_shadow.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">   
<gradient
    android:startColor="#20000000"
    android:endColor="@android:color/transparent"
    android:angle="270" >
</gradient>
</shape>

pour l'ombre au-dessus d'une vue above_shadow.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">   
<gradient
    android:startColor="#20000000"
    android:endColor="@android:color/transparent"
    android:angle="90" >
</gradient>
</shape>

et ainsi de suite pour l'ombre droite et gauche changez simplement l'angle du dégradé :)

Morteza Rastgoo
la source
où j'appelle le below_shadow? fond d'une vue?
Arthur Melo
1
Créez le fichier XML below_shadow, puis dans votre vue, ajoutez une "vue" dans votre mise en page et définissez below_shadow.xml comme arrière-plan de cette vue
Morteza Rastgoo
J'ai fait la même chose que vous avez dit, mais mon "above_shadow" n'est pas transparent lorsque je place cette vue dans la vue personnalisée. Cela fonctionne bien séparément. Que devrais-je faire?
SoYoung
18

Vous pouvez également utiliser une image de patch 9 comme arrière-plan de votre mise en page, ce qui permet des ombres plus «naturelles»:

entrez la description de l'image ici

Résultat:

entrez la description de l'image ici

Mettez l'image dans votre /res/drawabledossier.
Assurez-vous que l'extension de fichier est .9.png, non.png

À propos, il s'agit d'une modification (réduite à la taille minimale du carré) d'une ressource existante trouvée dans le dossier API 19 sdk resources.
J'ai laissé les marqueurs rouges, car ils ne semblent pas nuisibles, comme indiqué dans l'outil draw9patch.

[ÉDITER]

Environ 9 patchs, au cas où vous n'auriez jamais rien à voir avec eux.

Ajoutez-le simplement comme arrière-plan de votre vue.

Les zones marquées en noir (à gauche et en haut) s'étirent (verticalement, horizontalement).
Les zones marquées en noir (à droite, en bas) définissent la "zone de contenu" (où il est possible d'ajouter du texte ou des vues - vous pouvez appeler les régions non marquées "padding", si vous le souhaitez).

Tutoriel: http://radleymarx.com/blog/simple-guide-to-9-patch/

Phantômaxx
la source
1
Ajoutez-le simplement comme arrière-plan de votre vue. Les zones marquées en noir (à gauche et en haut) s'étirent (verticalement, horizontalement). Les zones marquées en noir (à droite, en bas) définissent la "zone de contenu" (où il est possible d'ajouter du texte ou des vues - appelez-la "padding", si vous le souhaitez). Tutoriel: radleymarx.com/blog/simple-guide-to-9-patch
Phantômaxx
9

Vous créez un fichier .xml dans drawable avec le nom drop_shadow.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--<item android:state_pressed="true">
        <layer-list>
            <item android:left="4dp" android:top="4dp">
                <shape>
                    <solid android:color="#35000000" />
                    <corners android:radius="2dp"/>
                </shape>
            </item>
            ...
        </layer-list>
    </item>-->
    <item>
        <layer-list>
            <!-- SHADOW LAYER -->
            <!--<item android:top="4dp" android:left="4dp">
                <shape>
                    <solid android:color="#35000000" />
                    <corners android:radius="2dp" />
                </shape>
            </item>-->
            <!-- SHADOW LAYER -->
            <item>
                <shape>
                    <solid android:color="#35000000" />
                    <corners android:radius="2dp" />
                </shape>
            </item>
            <!-- CONTENT LAYER -->
            <item android:bottom="3dp" android:left="1dp" android:right="3dp" android:top="1dp">
                <shape>
                    <solid android:color="#ffffff" />
                    <corners android:radius="1dp" />
                </shape>
            </item>
        </layer-list>
    </item>
</selector>

Ensuite:

<LinearLayout
...
android:background="@drawable/drop_shadow"/>
Anh Duy
la source
3

Utilisez cette seule ligne et j'espère que vous obtiendrez le meilleur résultat;

utilisation: android:elevation="3dp" Ajustez la taille autant que vous en avez besoin et c'est le moyen le meilleur et le plus simple d'obtenir l'ombre comme des boutons et d'autres ombres Android par défaut. Faites-moi savoir si cela a fonctionné!

Tamim
la source
@ MichałZiobro Utilisez-le avec vos mises en page comme si vous avez une mise en page sur une autre qui est plus petite et que vous souhaitez afficher l'ombre. ça devrait marcher. Vous constaterez peut-être que vos textes et vos boutons deviennent invisibles, mais lorsque vous exécuterez l'application, vous verrez la meilleure ombre. Je ne suis pas sûr que ce soit une sorte de bogue ou quelque chose du genre, mais dans mon cas, lorsque j'utilise ce code, cela rend toutes mes vues invisibles dans l'aperçu AS, mais fonctionne mieux dans l'application lorsque je la débogue / la lance dans mon appareil. Faites-moi savoir si cela a fonctionné ou non. Merci.
Tamim
3

Si vous avez déjà la bordure de la forme, ajoutez simplement une élévation:

<LinearLayout
    android:id="@+id/layout"
    ...
    android:elevation="2dp"
    android:background="@drawable/rectangle" />
Krzynool
la source
2
Qu'est-ce qu'un comportement sur API <21?
CoolMind
1
Malheureusement, cela ne fonctionne pas avant Lollipop, vous devriez donc utiliser certaines des autres réponses de cette question. Mais si vous ciblez des téléphones plus récents, c'est un moyen assez simple de le faire qui fonctionne bien.
Krzynool
2

1. Créez d'abord un nom de fichier xml shadow.xml dans le dossier "drawable" et copiez-y le code ci-dessous.

 <?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="#CABBBBBB" />
                <corners android:radius="10dp" />
            </shape>
        </item>

        <item
            android:bottom="6dp"
            android:left="0dp"
            android:right="6dp"
            android:top="0dp">
            <shape android:shape="rectangle">
                <solid android:color="@android:color/white" />
                <corners android:radius="4dp" />
            </shape>
        </item>
    </layer-list>

Ajoutez ensuite la liste des calques comme arrière-plan dans votre LinearLayout.

<LinearLayout
        android:id="@+id/header_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/shadow"
        android:orientation="vertical">
Sudhir singh
la source
merci beaucoup monsieur, votre code semble correct ...
John dahat le
1
@Johndahat its ok
Sudhir singh
1

Ya Mahdi aj --- pour RelativeLayout

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <gradient
                android:startColor="#7d000000"
                android:endColor="@android:color/transparent"
                android:angle="90" >
            </gradient>
            <corners android:radius="2dp" />
        </shape>
    </item>

    <item
        android:left="0dp"
        android:right="3dp"
        android:top="0dp"
        android:bottom="3dp">
        <shape android:shape="rectangle">
            <padding
                android:bottom="40dp"
                android:top="40dp"
                android:right="10dp"
                android:left="10dp"
                >
            </padding>
            <solid android:color="@color/Whitetransparent"/>
            <corners android:radius="2dp" />
        </shape>
    </item>
</layer-list>
سیدرسول میرعظیمی
la source
1

Je sais que c'est tard mais cela pourrait aider quelqu'un.

Vous pouvez utiliser un constraintLayout et ajouter la propriété suivante dans le xml,

        android:elevation="4dp"
harishanth raveendren
la source
0

J'ai trouvé le meilleur moyen de résoudre ce problème.

  1. Vous devez définir un arrière-plan rectangle solide sur la mise en page.

  2. Utilisez ce code - ViewCompat.setElevation(view , value)

  3. Sur l'ensemble de mises en page parent android:clipToPadding="false"

Sarthak Gandhi
la source
2
Si vous ne saviez pas, cela est la mise en œuvre actuelle de ViewCompat.setElevation()méthode sur la classe ViewCompat: public void setElevation(View view, float elevation) {}. Comme vous pouvez le voir, ce n'est pas implémenté. Je doute vraiment que cela vous aide, et je me demande vraiment si vous avez réellement testé votre propre réponse, lol
mradzinski