Android LinearLayout: adicione borda com sombra ao redor de um LinearLayout

147

Gostaria de criar a mesma borda deste LinearLayout como no exemplo:

insira a descrição da imagem aqui

Neste exemplo, podemos ver que a borda não é a mesma em todo o linearLayout. Como posso criar isso usando um arquivo drawable XML?

Por enquanto, eu só consigo criar uma borda simples em todo o LinearLayout assim:

<?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
fonte
1
você pode usar backgroundpropriedade para que ... criar um arquivo XML com a forma como o retângulo, cor e efeito de sombra para ele e defini-lo como plano de fundo para o seu layout linear ..
Pragnesh Ghodaシ
usar derrame de borda cinza e efeito preenchimento também
Pragnesh Ghodaシ
Eu acho, que o seu xml dois layout, dizer que um é de layout linear e interno é disposição relativa ter estofamento
Giru Bhai
@ Prag's Poderia me ajudar a criar esse arquivo xml, por favor?
Wwanopoulos
1
Uma maneira alternativa poderia ser usar uma imagem de 9 patches como plano de fundo para o seu layout. Isso permitiria uma sombra muito suave e desbotada (muito realista, na minha opinião).
Phantômaxx

Respostas:

257

Tente isso ..

<?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
fonte
@Hariharan Muito obrigado! Eu tentei o seu código e parece ok. Mas há uma coisa a fazer ainda, como posso adicionar uma borda fina (1dp) à esquerda e à direita do layout linear? (como o exemplo)
wawanopoulos
2
@wawanopoulos Basta substituir "0dp"por "1dp"na resposta de Hariharan.
Phantômaxx
você pode adicionar a cor #EAEAEA ao layout pai por isso vai ser como a imagem pergunta
Samad
3
Também gostaria de sugerir para isso, você pode usar <gradient>em sua <shape>para aumentar o efeito de fronteira, e também se é realmente o efeito o seu UI precisa em vez de apenas beira da cor sólida.
patrickjason91
certifique-se de ter um layout interno com match_parent e dê a margem 1 ao layout interno #
Shaktisinh Jadeja
82

É por isso que o CardView existe. CardView | Desenvolvedores Android
É apenas um FrameLayout que suporta elevação em dispositivos pré-pirulito.

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

Para usar isso, você precisa adicionar dependência a build.gradle:

compile 'com.android.support:cardview-v7:23.+'
Ray Suhyun Lee
fonte
como pode alterar cor da sombra
Aditay Kaushal
sombra é muito fraco stackoverflow.com/questions/49076188/...
user924
1
comportamento muito estranho em dispositivos com 4.4.4 (ou similar). Uma margem enorme é adicionada ao cardview e torna a interface do usuário muito feia.
Morteza Rastgoo 6/0318
Essa deve ser a resposta aceita. Uma pequena atualização embora. Você deve usar o androidx one -> androidx.cardview.widget.CardView
bogdan
59

Eu obtenho os melhores resultados usando um gráfico de 9 patches.

Você pode simplesmente criar um gráfico de patch 9 individual usando o seguinte editor: http://inloop.github.io/shadow4android/

Exemplo:

O gráfico de 9 patches:

O gráfico de 9 patches:

O resultado:

insira a descrição da imagem aqui

A fonte:

<LinearLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:orientation="vertical"
android:background="@drawable/my_nine_patch"
funcoder
fonte
1
Como ocultar a linha preta? Por favor ajude
Isaac Darlong
@Isaac salvar a imagem como my_nine_patch.9.png (.9.png é nove imagem lote)
Arun
ISSO É O MELHOR!
Numanqmr 20/02
35

Ok, eu sei que é tarde demais. mas eu tinha o mesmo requisito. eu resolvi assim

1. Crie primeiro um arquivo xml (exemplo: border_shadow.xml) na pasta "drawable" e copie o código abaixo para ele.

<?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. agora, no layout em que deseja a sombra (exemplo: LinearLayout), adicione isso no 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">

e isso funcionou para mim.

user3619170
fonte
20

Isto é tão simples:

Crie um arquivo drawable com um gradiente como este:

para sombra abaixo de uma 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>

para sombra acima de uma 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 assim por diante para a sombra direita e esquerda, basta alterar o ângulo do gradiente :)

Morteza Rastgoo
fonte
onde eu chamo de sombra abaixo? fundo de uma vista?
Arthur Melo
1
Criar below_shadow arquivo xml, em seguida, na sua opinião, adicionar um "View" na sua below_shadow.xml layout e conjunto como pano de fundo deste ponto de vista
Morteza Rastgoo
Fiz o mesmo que você disse, mas meu "above_shadow" não é transparente quando coloco essa exibição na exibição personalizada. Funciona bem separadamente. O que devo fazer?
SoYoung
18

Como alternativa, você pode usar uma imagem de 9 patches como plano de fundo para seu layout, permitindo sombras mais "naturais":

insira a descrição da imagem aqui

Resultado:

insira a descrição da imagem aqui

Coloque a imagem na sua /res/drawablepasta.
Verifique se a extensão do arquivo .9.pngnão está.png

A propósito, isso é uma modificação (reduzida ao tamanho mínimo quadrado) de um recurso existente encontrado na pasta de recursos da API 19 sdk.
Deixei os marcadores vermelhos, pois eles não parecem prejudiciais, como mostra a ferramenta draw9patch.

[EDITAR]

Cerca de 9 patches, caso você nunca tenha tido nada a ver com eles.

Basta adicioná-lo como plano de fundo da sua exibição.

As áreas marcadas em preto (esquerda e superior) se esticarão (vertical, horizontalmente).
As áreas marcadas em preto (à direita, embaixo) definem a "área de conteúdo" (onde é possível adicionar texto ou Visualizações - você pode chamar as regiões não marcadas de "preenchimento", se desejar).

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

Phantômaxx
fonte
1
Basta adicioná-lo como plano de fundo da sua exibição. As áreas marcadas em preto (esquerda e superior) se esticarão (vertical, horizontalmente). As áreas marcadas em preto (à direita, embaixo) definem a "área de conteúdo" (onde é possível adicionar texto ou Visualizações - chame-o de "preenchimento", se desejar). Tutorial: radleymarx.com/blog/simple-guide-to-9-patch
Phantômaxx
9

Você cria um arquivo .xml no drawable com o 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>

Então:

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

Use esta linha única e espero que você consiga o melhor resultado;

uso: android:elevation="3dp" ajuste o tamanho conforme necessário e esta é a melhor e mais simples maneira de obter a sombra como botões e outras sombras padrão do Android. Deixe-me saber se funcionou!

Tamim
fonte
@ MichałZiobro Use-o com seus layouts, como se você tivesse um layout em detrimento de outro que é menor e deseja mostrar a sombra. deve funcionar. Você pode achar que seus textos e botões ficam invisíveis, mas quando você executa o aplicativo, verá a melhor sombra. Não tenho certeza de que seja algum tipo de bug ou algo assim, mas no meu caso, quando uso esse código, todos os meus modos de exibição ficam invisíveis na visualização do AS, mas funcionam melhor no aplicativo quando eu depuro / inicio no meu dispositivo. Deixe-me saber se funcionou ou não. Obrigado.
Tamim
3

Se você já possui a borda da forma, adicione a elevação:

<LinearLayout
    android:id="@+id/layout"
    ...
    android:elevation="2dp"
    android:background="@drawable/rectangle" />
Krzynool
fonte
2
O que é um comportamento na API <21?
CoolMind 11/02/19
1
Infelizmente, ele não funciona pré-pirulito, então você deve usar algumas das outras respostas desta pergunta. Mas se você estiver segmentando telefones mais novos, é uma maneira muito fácil de fazer isso e que funciona bem.
22419 Krzynool
2

1. Primeiro, crie um nome de arquivo xml shadow.xml na pasta "drawable" e copie o código abaixo para ele.

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

Em seguida, adicione a lista de camadas como plano de fundo no seu 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
fonte
muito obrigado senhor, seu código parece ok ...
John dahat
1
@Johndahat its ok
Sudhir singh
1

Ya Mahdi aj --- para 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>
سیدرسول میرعظیمی
fonte
1

Eu sei que é tarde, mas poderia ajudar alguém.

Você pode usar um constraintLayout e adicionar a seguinte propriedade no xml,

        android:elevation="4dp"
harishanth raveendren
fonte
0

Eu encontrei a melhor maneira de resolver isso.

  1. Você precisa definir um plano de fundo retangular sólido no layout.

  2. Use este código - ViewCompat.setElevation(view , value)

  3. No conjunto de layouts pai android:clipToPadding="false"

Sarthak Gandhi
fonte
2
No caso de você não sabe, esta é a implementação atual do ViewCompat.setElevation()método na classe ViewCompat: public void setElevation(View view, float elevation) {}. Como você pode ver, não está implementado. Eu realmente duvido que ele vai ser de alguma ajuda, e realmente saber se você realmente testado a sua própria resposta, lol
mradzinski