Android LinearLayout: agrega borde con sombra alrededor de LinearLayout

147

Me gustaría crear el mismo borde de este LinearLayout como el ejemplo:

ingrese la descripción de la imagen aquí

En este ejemplo, podemos ver que el borde no es el mismo en todo el diseño lineal. ¿Cómo puedo crear esto usando un archivo dibujable XML?

Por ahora, solo he podido crear un borde simple alrededor de LinearLayout como este:

<?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
fuente
1
puede usar la backgroundpropiedad para eso ... cree un archivo XML con forma de rectángulo, color y efecto de sombra y
configúrelo
use trazo para el borde gris y el efecto de relleno también
Pragnesh Ghoda シ
Creo que sus dos diseños xml, digamos que uno es diseño lineal y el interior es diseño relativo con relleno
Giru Bhai
@ Prag's ¿Podría ayudarme a crear este archivo xml por favor?
wawanopoulos
1
Una forma alternativa podría ser usar una imagen de 9 parches como fondo para su diseño. Esto permitiría una sombra realmente suave y desvanecida (muy realista, en mi opinión).
Phantômaxx

Respuestas:

257

Prueba esto..

<?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
fuente
@Hariharan ¡Muchas gracias! probé tu código y parece estar bien. Pero, todavía hay una cosa que hacer, ¿cómo puedo agregar un borde delgado (1dp) a la izquierda y a la derecha de la distribución lineal? (como el ejemplo)
wawanopoulos
2
@wawanopoulos Simplemente reemplace "0dp"con "1dp"en la respuesta de Hariharan.
Phantômaxx
puede agregar el color #EAEAEA al diseño principal para que sea como la imagen de la pregunta
Samad
3
También sugeriría para esto, puede usar <gradient>en su <shape>para mejorar el efecto de borde, y también si realmente es el efecto que necesita su interfaz de usuario en lugar de solo un borde de color sólido.
patrickjason91
asegúrate de tener un diseño interno con match_parent y luego da margen 1 al diseño interno
Shaktisinh Jadeja
82

Por eso existe CardView. CardView | Desarrolladores de Android
Es solo un FrameLayout que admite la elevación en dispositivos pre-piruletas.

<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 esto, necesita agregar dependencia a build.gradle:

compile 'com.android.support:cardview-v7:23.+'
Ray Suhyun Lee
fuente
¿Cómo puede cambiar el color de las sombras?
Aditay Kaushal
la sombra es muy débil stackoverflow.com/questions/49076188/…
usuario924
1
Comportamiento muy extraño en dispositivos con 4.4.4 (o similar). Se agrega un margen enorme a cardview y hace que la interfaz de usuario sea muy fea.
Morteza Rastgoo
Esta debería ser la respuesta aceptada. Sin embargo, una pequeña actualización. Debería usar androidx one -> androidx.cardview.widget.CardView
bogdan
59

Obtengo los mejores resultados usando un gráfico de 9 parches.

Simplemente puede crear un gráfico individual de 9 parches utilizando el siguiente editor: http://inloop.github.io/shadow4android/

Ejemplo:

El gráfico de 9 parches:

El gráfico de 9 parches:

El resultado:

ingrese la descripción de la imagen aquí

La fuente:

<LinearLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:orientation="vertical"
android:background="@drawable/my_nine_patch"
Funcoder
fuente
1
¿Cómo puedo ocultar la línea negra? Por favor ayuda
Isaac Darlong
@Isaac guarda la imagen como my_nine_patch.9.png (.9.png es una imagen de 9 lotes)
lanzará el
¡ESTO ES LO MEJOR!
Numanqmr
35

Está bien, sé que esto es demasiado tarde. Pero tenía el mismo requisito. resolví así

1. Primero cree un archivo xml (ejemplo: border_shadow.xml) en la carpeta "dibujable" y copie el código a continuación.

<?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.ahora en el diseño donde desea la sombra (ejemplo: LinearLayout) agregue esto en android: fondo

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

Y eso funcionó para mí.

usuario3619170
fuente
20

Esto es muy simple:

Cree un archivo dibujable con un degradado como este:

para sombra debajo de 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>

para sombra sobre 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>

y así sucesivamente para la sombra derecha e izquierda solo cambia el ángulo del gradiente :)

Morteza Rastgoo
fuente
donde llamo la siguiente sombra? fondo de una vista?
Arthur Melo
1
Cree el archivo xml below_shadow, luego en su vista, agregue una "Vista" en su diseño y establezca below_shadow.xml como fondo de esta vista
Morteza Rastgoo
Hice lo mismo que dijiste, pero mi "above_shadow" no es transparente cuando pongo esa vista en la vista personalizada. Funciona bien por separado. ¿Qué tengo que hacer?
SoYoung
18

Como alternativa, puede usar una imagen de 9 parches como fondo para su diseño, permitiendo sombras más "naturales":

ingrese la descripción de la imagen aquí

Resultado:

ingrese la descripción de la imagen aquí

Pon la imagen en tu /res/drawablecarpeta.
Asegúrese de que la extensión del archivo sea .9.png, no.png

Por cierto, esta es una modificación (reducida al tamaño cuadrado mínimo) de un recurso existente que se encuentra en la carpeta de recursos API 19 SDK.
Dejé los marcadores rojos, ya que no parecen ser dañinos, como se muestra en la herramienta draw9patch.

[EDITAR]

Alrededor de 9 parches, en caso de que nunca haya tenido nada que ver con ellos.

Simplemente agréguelo como fondo de su Vista.

Las áreas marcadas en negro (izquierda y arriba) se estirarán (verticalmente, horizontalmente).
Las áreas marcadas en negro (derecha, abajo) definen el "área de contenido" (donde es posible agregar texto o Vistas; si lo desea, puede llamar a las regiones sin marcar "relleno").

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

Phantômaxx
fuente
1
Simplemente agréguelo como fondo de su Vista. Las áreas marcadas en negro (izquierda y arriba) se estirarán (verticalmente, horizontalmente). Las áreas marcadas en negro (derecha, abajo) definen el "área de contenido" (donde es posible agregar texto o Vistas, llámelo "relleno", si lo desea). Tutorial: radleymarx.com/blog/simple-guide-to-9-patch
Phantômaxx
9

Crea un archivo .xml en dibujable con el nombre 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>

Luego:

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

Use esta línea única y esperemos que logre el mejor resultado;

uso: android:elevation="3dp" ajusta el tamaño todo lo que necesites y esta es la mejor y más simple forma de lograr la sombra como botones y otras sombras predeterminadas de Android. ¡Avísame si funcionó!

Tamim
fuente
@ MichałZiobro Úselo con sus diseños, como si tuviera un diseño sobre otro que sea más pequeño y quiera mostrar la sombra. deberia de funcionar. Es posible que sus textos y botones se vuelvan invisibles, pero cuando ejecute la aplicación verá la mejor sombra. No estoy seguro de que sea algún tipo de error o algo así, pero en mi caso cuando uso ese código, hace que todas mis vistas sean invisibles en la vista previa de AS, pero funciona mejor en la aplicación cuando la depuro / inicio en mi dispositivo. Avísame si funcionó o no. Gracias.
Tamim
3

Si ya tiene el borde de la forma, simplemente agregue elevación:

<LinearLayout
    android:id="@+id/layout"
    ...
    android:elevation="2dp"
    android:background="@drawable/rectangle" />
Krzynool
fuente
2
¿Qué es un comportamiento en API <21?
CoolMind
1
Desafortunadamente, no funciona antes de Lollipop, por lo que debe usar algunas de las otras respuestas de esta pregunta. Pero si está apuntando a teléfonos más nuevos, esta es una forma bastante fácil de hacerlo que funciona bien.
Krzynool
2

1. Primero cree un nombre de archivo xml shadow.xml en la carpeta "dibujable" y copie el código siguiente.

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

Luego agregue la lista de capas como fondo en su 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
fuente
muchas gracias señor, su código parece estar bien ...
John dahat
1
@Johndahat está bien
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>
سیدرسول میرعظیمی
fuente
1

Sé que es tarde, pero podría ayudar a alguien.

Puede usar un restrictintLayout y agregar la siguiente propiedad en el xml,

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

Encontré la mejor manera de abordar esto.

  1. Debe establecer un fondo rectángulo sólido en el diseño.

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

  3. En el conjunto de diseño primario android:clipToPadding="false"

Sarthak Gandhi
fuente
2
En caso de que no lo sabía, esto es la implementación actual del ViewCompat.setElevation()método en la clase ViewCompat: public void setElevation(View view, float elevation) {}. Como puede ver, no está implementado. Realmente dudo que sea de alguna ayuda, y realmente me pregunto si realmente
probaste