Android View shadow

102

Eu procurei e não consegui encontrar uma maneira adequada de fazer isso. Eu quero ter os seguintes efeitos de sombra em minhas visualizações: insira a descrição da imagem aqui

insira a descrição da imagem aqui

Para ser sincero, não sei se este segundo é feito aplicando o efeito de sombra. Alguma ideia?

longwalker
fonte
1
Você quis dizer isso? stackoverflow.com/questions/4406524/… (verifique a resposta com maior voto, não a resposta marcada)
Luke Vo
1
@DatVM, obrigado, isso parece funcionar, mas eu estava pensando que talvez existam ferramentas integradas no SDK do Android. Por exemplo, adicionar sombras
projetadas
Pergunta semelhante - stackoverflow.com/q/52954743/9640177 - adicionando sombra ao drawable vetorial
mayank1513

Respostas:

158

Sei que essa pergunta já foi respondida, mas quero que você saiba que encontrei um drawableem Android Studioque é muito semelhante às fotos que você tem na pergunta: Dê uma olhada nisso:

android:background="@drawable/abc_menu_dropdown_panel_holo_light"

Se parece com isso:

insira a descrição da imagem aqui

Espero que seja útil

Editar

A opção acima é para as versões mais antigas do, Android Studioportanto, talvez você não encontre. Para versões mais recentes:

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

Além disso, se você quiser ter seu próprio formato personalizado, sugiro usar um software de desenho como o Photoshope desenhá-lo.

insira a descrição da imagem aqui

Não se esqueça de salvá-lo como .9.pngarquivo (exemplo my_background.9.png:)

Leia a documentação: Draw 9-patch

Editar 2

Uma solução ainda melhor e menos trabalhosa é usar um CardViewe definir app:cardPreventCornerOverlap="false"para evitar que as visualizações se sobreponham às bordas:

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

Além disso, certifique-se de ter incluído a versão mais recente no build.gradle, a atual é

compile 'com.android.support:cardview-v7:26.0.0'
Rick
fonte
Obrigado, na verdade, é muito semelhante. Eu também achei "layout de cartão do google" para Android, e eles são muito legais!
longwalker
6
Impressionante. Apenas um FYI para futuros espectadores /<sdk-path>/extras/android/support.
theblang de
2
Que tal usar umcardView
Alex Chengalan
100

Estou usando o Android Studio 0.8.6 e não consegui encontrar:

android:background="@drawable/abc_menu_dropdown_panel_holo_light"

então eu encontrei isto:

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

e é assim:

insira a descrição da imagem aqui

Repo
fonte
1
mas não podemos adicionar raio de canto com ele ?!
Fay007 01 de
40

colocar um fundo de @android:drawable/dialog_holo_light_frame, dá sombra, mas você não pode mudar a cor de fundo nem o estilo da borda, então é melhor se beneficiar da sombra disso, enquanto ainda pode colocar um fundo através da lista de camadas

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

salve-o na pasta drawable em dizer shadow.xml

para atribuí-lo a uma visão, no arquivo de layout xml defina o fundo dele

android:background="@drawable/shadow"
Mohamed Selim
fonte
Você verificou se funciona? O segundo <item> não faz nada. Não consigo alterá-lo para cantos transparentes ou arredondados.
zeeshan
2
De tudo o que experimentei, esta é a única que funciona, obrigado.
Shyam Sunder
1
solução fantástica
user1974368
34

Crie card_background.xml na pasta res / drawable com o seguinte código:

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

Em seguida, adicione o seguinte código ao elemento para o qual deseja o layout do cartão

android:background="@drawable/card_background"

a linha a seguir define a cor da sombra do cartão

<solid android:color="#BDBDBD"/>
Vivek Varma
fonte
10
Esta não é realmente uma sombra - porque ela não desaparece. É mais como uma fronteira em dois dos lados.
ban-geoengineering
não é uma sombra
ShadeToD
24

O CardView oferece a verdadeira sombra no Android 5+ e possui uma biblioteca de suporte. Basta envolver sua visualização com isso e pronto.

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

Requer a próxima dependência.

dependencies {
    ...
    compile 'com.android.support:cardview-v7:21.0.+'
}
Ilya Gazman
fonte
1
Esta é a única resposta certa, uma vez que CardViewtambém possui níveis de sombra variáveis ​​para diferentes elevações no modo de compatibilidade.
Jarett Millard de
Eu recomendo o MaterialCardView porque é mais claro e tem mais recursos.
H. Farid
12

Isso pode ser tarde, mas para aqueles que ainda estão procurando uma resposta para isso eu encontrei um projeto no git hub e este é o único que realmente atende às minhas necessidades. android-materialshadowninepatch

Basta adicionar esta linha em sua dependência build.gradle

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

Felicidades. polegar para o criador! happycodings

Ralphgabb
fonte
Ei @ralphgabb, isso ainda funciona bem para você ou você tem uma solução melhor para dispositivos pré-pirulito?
Swapnil
@Swapnil não tenho certeza se o AndroidX suporta isso agora, no entanto, não estou mais suportando dispositivos pré-Marshmallow.
ralphgabb
5

Eu sei que isso é estupidamente hacky,
mas se você quiser oferecer suporte na v21, aqui estão minhas conquistas.

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>

Aqui está o resultado:

Sob v21 (isso é o que você fez com xml) insira a descrição da imagem aqui

Acima de v21 (renderização de elevação real) insira a descrição da imagem aqui

  • A única diferença significativa é que ele ocupará o espaço interno da visualização, de modo que sua área de conteúdo real pode ser menor do que > = dispositivos pirulitos .
wonsuc
fonte
3

Se você precisar que as sombras sejam aplicadas corretamente, você deve fazer o seguinte.

Considere esta visualização, definida com um drawable de fundo:

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

O drawable de fundo é definido como um retângulo com cantos arredondados:

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

Esta é a maneira recomendada de aplacar sombras, verifique https://developer.android.com/training/material/shadows-clipping.html#Shadows

Shangeeth Sivan
fonte
2

Use a propriedade de elevação para efeito de sombra:

<YourView
    ...
    android:elevation="3dp"/>
Ofek Ashery
fonte
Usar Elevation requer que o dispositivo execute o Lollipop.
Shane Rowatt
2

Crie um drawable de plano de fundo como este para mostrar a sombra arredondada.

<?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
fonte
Adicione uma descrição também para o código que você forneceu.
Mangaldeep Pannu de
Muito boa solução única para xml
Bruno Bieri
2

Esta pergunta pode ser antiga, mas para qualquer pessoa no futuro que queira uma maneira simples de obter efeitos de sombra complexos, verifique minha biblioteca aqui https://github.com/BluRe-CN/ComplexView

Usando a biblioteca, você pode alterar as cores das sombras, ajustar as bordas e muito mais. Aqui está um exemplo para conseguir o que você busca.

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

Para alterar a cor da sombra, use app: shadowColor = "seu código de cor".

BluRe.CN
fonte
1

use esta forma como plano de fundo:

<?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>
Sr. Hosseini
fonte