¿Cómo dibujar el borde en un solo lado de un diseño lineal?

186

Puedo dibujar el borde en un diseño lineal, pero se dibuja en todos los lados. Quiero restringirlo solo al lado derecho, como lo hace en CSS (border-right: 1px solid red;).

He intentado esto, pero aún se basa en todos los lados:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
    <shape android:shape="rectangle" >
        <stroke
            android:height="2dp"
            android:width="2dp"
            android:color="#FF0000" />

        <solid android:color="#000000" />

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

        <corners
            android:bottomLeftRadius="0dp"
            android:bottomRightRadius="5dp"
            android:radius="1dp"
            android:topLeftRadius="5dp"
            android:topRightRadius="0dp" />
    </shape>
</item>

¿Alguna sugerencia sobre cómo lograr esto?

Por cierto, no quiero usar el truco de poner una vista de ancho 1dp en el lado requerido.

Nitin Bansal
fuente
puedes usar drawableLeft en tu diseño
njzk2

Respuestas:

359

Puede usar esto para obtener borde en un lado

<?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="#FF0000" />
    </shape>
</item>
<item android:left="5dp">
    <shape android:shape="rectangle">
        <solid android:color="#000000" />
    </shape>
</item>
</layer-list>

EDITADO

Como muchos, incluyéndome a mí, querían tener un borde de un lado con fondo transparente, he implementado uno BorderDrawableque podría darme bordes con diferentes tamaños y colores de la misma manera que usamos css. Pero esto no se pudo usar a través de xml. Para admitir XML, he agregado un BorderFrameLayouten el que su diseño se puede ajustar.

Vea mi github para la fuente completa.

Vivek Khandelwal
fuente
55
¿Qué pasa si desea un color sólido basado en alfa con un borde inferior? He estado pensando en una solución para eso con la API XML Drawable de Android, pero no puedo resolverlo.
Mario Lenci
Esto no funcionó para mí: curiosamente, el inverso de lo que quería era un color más oscuro en el interior, con el degradado gris que superpuse para los huéspedes. He estado pensando en hacer un rectángulo dibujable en un cierto tamaño para poner como dibujable a la izquierda en el elemento. Esto no parece tan aerodinámico.
jbenowitz
@jbenowitz: el orden del elemento en la lista de capas es más importante. Si reviertes, obtendrás esos resultados.
Vivek Khandelwal
He solucionado esto agregando un trazo al color del borde y la forma que queda del color del botón. Eso hizo el truco.
jbenowitz
243

Fácil como un pastel, permitiendo un bg transparente:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:angle="0"
        android:startColor="#f00"
        android:centerColor="@android:color/transparent"
        android:centerX="0.01" />
</shape>

Cambie el ángulo para cambiar la ubicación del borde:

  • 0 = izquierda
  • 90 = abajo
  • 180 = derecha
  • 270 = arriba
Oded Breiner
fuente
19
Esta es, de lejos, la mejor respuesta aquí, lástima que no se haya
votado a
11
Agradable, sin embargo, ciertamente no lo describiría como "fácil como el pastel".
funkybro
77
Esto no funciona si necesita un borde más grueso o si necesita bordes en varios lados.
principio holográfico
1
@codeman: use esto como fondo para su vista, luego heredará su altura.
Oded Breiner
2
¿Cómo ajustar el trazo o el ancho del borde?
Ruturaj Patil
101

También es posible implementar lo que quieras usando una sola capa

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

    <item
        android:bottom="-5dp"
        android:right="-5dp"
        android:top="-5dp">
        <shape android:shape="rectangle" >
            <solid android:color="@color/color_of_the_background" />

            <stroke
                android:width="5dp"
                android:color="@color/color_of_the_border" />
        </shape>
    </item>

</layer-list>

de esta manera sólo borde izquierdo es visible, pero se puede lograr cualquier combinación que desee jugar con bottom, left, righty toplos atributos del itemelemento

Viktor Grekov
fuente
3
Esto es definitivamente útil cuando tiene otro color de fondo y desea superponer este bg dibujable con borde. (y)
Aung Pyae
3
Exactamente lo que necesito, pero ¿es correcto usar rellenos negativos?
IlyaEremin
1
Esta es la mejor solución. Me molesta lo que hace -5dp allí.
Amit Kumar
1
El relleno negativo es común en HTML / CSS. Simplemente empuja las cosas en la otra dirección. En mi experiencia, parece perfectamente válido también en Android.
spaaarky21
Las implementaciones que utilizan márgenes negativos no funcionan bien si su diseño tiene clipChildren = false o clipToPadding = false. Si este es el caso, puede usar la solución con dos rectángulos superpuestos, como el propuesto por Vivek Khandelwal
Jesús Barrera
80

Para obtener un borde en un solo lado de un dibujo, aplique un negativo inseta los otros 3 lados (haciendo que esos bordes se dibujen fuera de la pantalla).

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetTop="-2dp" 
    android:insetBottom="-2dp"
    android:insetLeft="-2dp">

    <shape android:shape="rectangle">
        <stroke android:width="2dp" android:color="#FF0000" />
        <solid android:color="#000000" />
    </shape>

</inset>

ingrese la descripción de la imagen aquí

Este enfoque es similar a la respuesta de naykah, pero sin el uso de a layer-list.

soldado
fuente
44
Esta es la mejor respuesta de la OMI
James
muy buena respuesta, solo necesito cambiar el ancho y el recuadro a 10dp :) Y más, necesito un borde a la izquierda, así que cambio android: insetLeft a android: insetRight. ¡Tan sencillo! Mantener clic en el botón Material: D
Phuong
Exactamente lo que necesitaba, cambiar insertXen la parte superior para decidir qué bordes mostrar y qué no.
CularBytes
Incluso puedo tener un color sólido de @null y luego este método no causa sobregiro. Genio. ¡Gracias!
Unknownweirdo
2
Atención: esto cambiará el contenido de su vista y también lo cambiará de tamaño. Usar con cuidado.
vovahost
7

Como alternativa (si no desea utilizar el fondo), puede hacerlo fácilmente haciendo una vista de la siguiente manera:

<View
    android:layout_width="2dp"
    android:layout_height="match_parent"
    android:background="#000000" />

Para tener un borde derecho solamente, colóquelo después del diseño (donde desea tener el borde):

<View
    android:layout_width="2dp"
    android:layout_height="match_parent"
    android:background="#000000" />

Para tener solo un borde izquierdo, colóquelo antes del diseño (donde desea tener el borde):

Trabajó para mí ... Espero que sea de alguna ayuda ...

Nishant Jha
fuente
6

Pude lograr el efecto con el siguiente código

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:left="0dp" android:right="-5dp" android:top="-5dp" android:bottom="-5dp">
        <shape
        android:shape="rectangle">
            <stroke android:width="1dp" android:color="#123456" />
        </shape>
    </item>
</layer-list>

Puede ajustarse a sus necesidades de posición en el borde cambiando la dirección de desplazamiento

IvelinStanchev
fuente
5
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" >
        <shape>
            <solid
                android:color="#f28b24" />
            <stroke
                android:width="1dp"
                android:color="#f28b24" />
            <corners
                android:radius="0dp"/>
            <padding
                android:left="0dp"
                android:top="0dp"
                android:right="0dp"
                android:bottom="0dp" />
        </shape>
    </item>
    <item>
        <shape>
            <gradient
                android:startColor="#f28b24"
                android:endColor="#f28b24"
                android:angle="270" />
            <stroke
                android:width="0dp"
                android:color="#f28b24" />
            <corners
                android:bottomLeftRadius="8dp"
                android:bottomRightRadius="0dp"
                android:topLeftRadius="0dp"
                android:topRightRadius="0dp"/>
            <padding
                android:left="10dp"
                android:top="10dp"
                android:right="10dp"
                android:bottom="10dp" />
        </shape>
    </item>
</selector>
alejandrocordon
fuente
5

Otro gran ejemplo ejemplo

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<inset xmlns:android="http://schemas.android.com/apk/res/android"
     android:insetRight="-2dp">

     <shape android:shape="rectangle">
         <corners
             android:bottomLeftRadius="4dp"
             android:bottomRightRadius="0dp"
             android:topLeftRadius="4dp"
             android:topRightRadius="0dp" />
         <stroke
             android:width="1dp"
             android:color="@color/nasty_green" />
         <solid android:color="@android:color/transparent" />
     </shape>

</inset>
Muklas
fuente
2

No hay mención sobre los archivos de nueve parches aquí. Sí, tiene que crear el archivo, sin embargo, es un trabajo bastante fácil y es realmente una solución de " versión cruzada y soporte de transparencia ". Si el archivo se coloca en el drawable-nodpidirectorio, funciona en pxbase, y en los drawable-mdpitrabajos aproximadamente como base dp (gracias al remuestreo).

El archivo de ejemplo para la pregunta original ( border-right: 1px solid red; ) está aquí:

http://ge.tt/517ZIFC2/v/3?c

Simplemente colóquelo en el drawable-nodpidirectorio.

Cuarc
fuente
2

Fronteras de diferentes colores. Usé 3 artículos.

<?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="@color/colorAccent" />
        </shape>
    </item>
    <item android:top="3dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/light_grey" />
        </shape>
    </item>
    <item
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp"
        android:top="3dp">
        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimary" />
        </shape>
    </item>
</layer-list>
Ritesh
fuente