Android LinearLayout: aggiungi un bordo con ombra attorno a un LinearLayout


147

Vorrei creare lo stesso bordo di questo LinearLayout dell'esempio:

inserisci qui la descrizione dell'immagine

In questo esempio, possiamo vedere che il bordo non è lo stesso attorno a linearLayout. Come posso crearlo usando un file drawable XML?

Per ora, ho solo potuto creare un bordo semplice attorno a LinearLayout in questo modo:

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

1
puoi usare la backgroundproprietà per quello ... crea un file XML con forma come rettangolo, effetto di colore e ombra e
impostalo

usa anche il tratto per il bordo grigio e l'effetto di imbottitura
Pragnesh Ghoda

Penso che i suoi due xml di layout, dicano uno sia layout lineare e interno sia layout relativo con imbottitura
Giru Bhai

@ Prag's Potresti aiutarmi per la creazione di questo file XML per favore?
wawanopoulos,

1
Un modo alternativo potrebbe essere l'utilizzo di un'immagine 9 patch come sfondo per il layout. Ciò consentirebbe un'ombra molto liscia e sbiadita (molto realistica, secondo me).
Phantômaxx,

Risposte:


257

Prova questo..

<?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 Grazie mille! ho provato il tuo codice e sembra ok. Ma c'è ancora una cosa da fare, come posso aggiungere un bordo sottile (1dp) a sinistra e a destra del linearlayout? (come nell'esempio)
wawanopoulos,

2
@wawanopoulos Basta sostituire "0dp"con "1dp"nella risposta di Hariharan.
Phantômaxx,

puoi aggiungere il colore #EAEAEA al layout principale in modo che sia proprio come l'immagine della domanda
Samad,

3
Vorrei anche suggerire per questo, è possibile utilizzare <gradient>nel tuo <shape>per migliorare l'effetto del bordo, e anche se è davvero l'effetto di cui la tua interfaccia utente ha bisogno invece del solo bordo di colore solido.
patrickjason91,

assicurati di avere un layout interno con match_parent, quindi dai un margine 1 al layout interno
Shaktisinh Jadeja,

82

Ecco perché CardView esiste. CardView | Sviluppatori Android
È solo un FrameLayout che supporta l'elevazione nei dispositivi pre-lecca-lecca.

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

Per usare questo è necessario aggiungere dipendenza a build.gradle:

compile 'com.android.support:cardview-v7:23.+'

come può cambiare il colore dell'ombra
Aditay Kaushal,


1
comportamento molto strano nei dispositivi con 4.4.4 (o simili). Un grande margine viene aggiunto a cardview in e rende l'interfaccia utente molto brutta.
Morteza Rastgoo,

Questa dovrebbe essere la risposta accettata. Un piccolo aggiornamento però. Dovresti usare quello androidx -> androidx.cardview.widget.CardView
bogdan

59

Ottengo i risultati migliori usando un grafico a 9 patch.

Puoi semplicemente creare un singolo grafico a 9 patch usando il seguente editor: http://inloop.github.io/shadow4android/

Esempio:

La grafica di 9 patch:

La grafica di 9 patch:

Il risultato:

inserisci qui la descrizione dell'immagine

La fonte:

<LinearLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:orientation="vertical"
android:background="@drawable/my_nine_patch"

1
Come posso nascondere la linea nera? Si prega di aiuto
Isaac Darlong

@Isaac Salva l'immagine come my_nine_patch.9.png (.9.png è 9 immagini in batch)
Arun

QUESTO È IL MIGLIORE!
Numanqmr

35

okay, so che è troppo tardi. ma avevo lo stesso requisito. ho risolto in questo modo

1.Prima di creare un file xml (esempio: border_shadow.xml) nella cartella "drawable" e copiarvi il codice sottostante.

<?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.Con il layout in cui si desidera l'ombra (esempio: LinearLayout) aggiungere questo in Android: sfondo

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

e quello ha funzionato per me.


20

Questo è così semplice:

Crea un file disegnabile con una sfumatura come questa:

per l'ombra sotto una vista 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>

per ombra sopra una vista 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>

e così via per l'ombra destra e sinistra basta cambiare l'angolo del gradiente :)


dove chiamo below_shadow? sfondo di una vista?
Arthur Melo,

1
Crea il file xml below_shadow, quindi nella tua vista, aggiungi una "Vista" nel tuo layout e imposta below_shadow.xml come sfondo di questa vista
Morteza Rastgoo

Ho fatto lo stesso come hai detto, ma il mio "above_shadow" non è trasparente quando ho inserito quella vista nella vista personalizzata. Funziona bene separatamente. Cosa dovrei fare?
SoYoung,

18

In alternativa, è possibile utilizzare un'immagine 9 patch come sfondo per il layout, consentendo ombre più "naturali":

inserisci qui la descrizione dell'immagine

Risultato:

inserisci qui la descrizione dell'immagine

Metti l'immagine nella tua /res/drawablecartella.
Assicurati che l'estensione del file sia .9.png, no.png

A proposito, si tratta di una modifica (ridotta alla dimensione minima quadrata) di una risorsa esistente trovata nella cartella delle risorse sdk dell'API 19.
Ho lasciato gli indicatori rossi, poiché non sembrano essere dannosi, come mostrato nello strumento draw9patch.

[MODIFICARE]

Circa 9 patch, nel caso in cui non avessi mai avuto nulla a che fare con loro.

Aggiungilo semplicemente come sfondo della tua vista.

Le aree contrassegnate in nero (a sinistra e in alto) si allungheranno (verticalmente, orizzontalmente).
Le aree contrassegnate in nero (a destra, in basso) definiscono "l'area del contenuto" (dove è possibile aggiungere testo o viste - è possibile chiamare le aree non contrassegnate "riempimento", se lo si desidera).

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


1
Aggiungilo semplicemente come sfondo della tua vista. Le aree contrassegnate in nero (a sinistra e in alto) si allungheranno (verticalmente, orizzontalmente). Le aree contrassegnate in nero (a destra, in basso) definiscono "l'area del contenuto" (dove è possibile aggiungere testo o viste - chiamalo "riempimento", se lo desideri). Tutorial: radleymarx.com/blog/simple-guide-to-9-patch
Phantômaxx

9

Si crea un file .xml in drawable con il nome 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>

Poi:

<LinearLayout
...
android:background="@drawable/drop_shadow"/>

3

Usa questa linea singola e spero che otterrai il miglior risultato;

Usa: android:elevation="3dp" regola le dimensioni di cui hai bisogno e questo è il modo migliore e più semplice per ottenere l'ombra come pulsanti e altre ombre Android predefinite. Fammi sapere se ha funzionato!


@ MichałZiobro Usalo con i tuoi layout come se avessi un layout su un altro che è più piccolo e vuoi mostrare l'ombra. dovrebbe funzionare. È possibile che i pulsanti e i pulsanti diventino invisibili, ma quando eseguirai l'app vedrai l'ombra migliore. Non sono sicuro che sia una specie di bug o qualcosa del genere, ma nel mio caso quando uso quel codice rende tutte le mie viste invisibili nell'anteprima di AS ma funziona meglio nell'app quando eseguo il debug / avvio nel mio dispositivo. Fammi sapere se ha funzionato o meno. Grazie.
Tamim,

3

Se hai già il bordo dalla forma, aggiungi semplicemente elevazione:

<LinearLayout
    android:id="@+id/layout"
    ...
    android:elevation="2dp"
    android:background="@drawable/rectangle" />

2
Che cos'è un comportamento su API <21?
CoolMind,

1
Sfortunatamente non funziona prima di Lollipop, quindi dovresti usare alcune delle altre risposte a questa domanda. Ma se stai prendendo di mira i telefoni più recenti, questo è un modo abbastanza semplice per farlo che funziona bene.
Krzynool,

2

1.Prima di creare un nome file xml shadow.xml nella cartella "drawable" e copiarvi il codice sottostante.

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

Quindi aggiungi l'elenco dei livelli come sfondo nel tuo LinearLayout.

<LinearLayout
        android:id="@+id/header_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/shadow"
        android:orientation="vertical">

grazie mille signore, il suo codice sembra ok ...
John dahat,

1
@Johndahat è ok
Sudhir singh

1

Ya Mahdi aj --- per 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>

1

So che è tardi ma potrebbe aiutare qualcuno.

Puoi utilizzare un restringLayout e aggiungere la seguente proprietà nel file XML,

        android:elevation="4dp"

0

Ho trovato il modo migliore per affrontare questo.

  1. È necessario impostare uno sfondo di rettangolo solido sul layout.

  2. Usa questo codice - ViewCompat.setElevation(view , value)

  3. Sul set di layout principale android:clipToPadding="false"


2
Nel caso non lo sapeva, questo è l'attuale implementazione del ViewCompat.setElevation()metodo nella classe ViewCompat: public void setElevation(View view, float elevation) {}. Come puoi vedere, non è implementato. Dubito davvero che sarà di alcun aiuto, e mi chiedo davvero se hai effettivamente testato la tua risposta, lol
mradzinski,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.