Línea vertical usando XML dibujable

162

Estoy tratando de descubrir cómo definir una línea vertical (1dp de grosor) para usar como dibujable.

Para hacer una horizontal, es bastante sencillo:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">
    <stroke android:width="1dp" android:color="#0000FF"/>
    <size android:height="50dp" />     
</shape>

La pregunta es, ¿cómo hacer que esta línea sea vertical?

Sí, existen soluciones alternativas, como dibujar una forma de rectángulo de 1px de grosor, pero eso complica el XML dibujable, si consta de múltiples <item>elementos.

¿Alguien tuvo alguna posibilidad con esto?

ACTUALIZAR

El caso aún está sin resolver. Sin embargo, para cualquier persona en una cruzada de documentación de Android, puede encontrar esto útil: Falta el manual XML de Android

ACTUALIZAR

No encontré otra forma que no sea la que marqué como correcta. Sin embargo, hace el truco se siente un poco "pesado", por lo tanto, si sabes la respuesta, no olvides compartirla;)

Kaspa
fuente

Respuestas:

394

En lugar de una forma, puedes probar con View:

<View
    android:layout_width="1dp"
    android:layout_height="fill_parent"
    android:background="#FF0000FF" />

Solo he usado esto para líneas horizontales, pero creo que funcionaría también para líneas verticales.

Utilizar:

<View
    android:layout_width="fill_parent"
    android:layout_height="1dp"
    android:background="#FF0000FF" />

para una linea horizontal.

CommonsWare
fuente
44
gracias Mark :)! Soy consciente de que puedo usar una vista para lograr esto. La cuestión es que estoy armando una vista un poco más compleja que quiero usar como dibujable para el fondo de una celda de tabla. Hay diferentes tipos de formas / gradientes / líneas allí. El uso de una vista SERÍA una solución, sin embargo, tendría que ponerlo en una "capa" de dibujo diferente y eso es potencialmente dispararle en el pie cuando encuentre un cambio de tamaño, etc. Me pregunto por qué no hay documentación sobre el " forma "xmls, tal vez alguien de google podría iluminarnos? :)
Kaspa
1
Usar marginRight / Start y Left / End también es a veces interesante para obtener espacio en los lados.
George
108

Puede anidar su forma dentro de una etiqueta de rotación.

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="90"
    android:toDegrees="90">
    <shape 
        android:shape="line">
        <stroke
            android:width="1dp"
            android:color="#ff00ff"
            android:dashWidth="1dp"
            android:dashGap="2dp" />
    </shape>
</rotate>

Sin embargo, el único problema es que los parámetros de diseño definidos en su diseño xml serán las dimensiones utilizadas para dibujar la forma original. Lo que significa que si desea que su línea tenga 30dp de altura, debe definir un layout_width de 30dp en su diseño xml. Pero el ancho final también será de 30dp en ese caso, lo que probablemente no sea deseable para la mayoría de las situaciones. Esto esencialmente significa que tanto el ancho como la altura deben ser el mismo valor, el valor de la longitud deseada para la línea. No pude averiguar cómo solucionar esto.

Esta parece ser la solución de "modo Android", pero a menos que haya alguna solución o solución para el problema de dimensiones que menciono, es probable que esto no funcione para la mayoría de las personas. Lo que realmente necesitamos es un atributo de orientación en <forma /> o <trazo />.

También puede intentar hacer referencia a otro dibujable en los atributos de la etiqueta de rotación, como:

<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="90"
    android:toDegrees="90"
    android:drawable="@drawable/horizontal_line" />

Sin embargo, no he probado esto y espero que tenga los mismos problemas.

- EDITAR -

Oh, en realidad descubrí una solución. Puede usar un margen negativo en su diseño xml para deshacerse del espacio extra no deseado. Como:

<ImageView
    android:layout_width="35dp"
    android:layout_height="35dp"
    android:layout_marginLeft="-15dp"
    android:layout_marginRight="-15dp"
    android:src="@drawable/dashed_vertical_line" />
cephus
fuente
44
mientras que el margen negativo funcionará para el 99% de los dispositivos ... solo sé que hay dispositivos que forzarán el cierre si haces esto. Algunos dispositivos tienen problemas para inflar un margen negativo
Kent Andersen
2
@cephus Uso tu primer código, pero necesito la línea en la parte superior de la vista. Está en el centro de mi vista. ¿Cómo puedo configurar una gravedad (dentro del archivo xml de forma)?
Behzad
20

Puedes usar el atributo rotar

 <item>
    <rotate
        android:fromDegrees="90"
        android:toDegrees="90"
        android:pivotX="50%"
        android:pivotY="50%" >
        <shape
            android:shape="line"
            android:top="1dip" >
            <stroke
                android:width="1dip"
                 />
        </shape>
    </rotate>
</item>
usuario4679242
fuente
66
Esta es definitivamente una respuesta mejor (o la mejor) porque, mientras que la respuesta de @ commonsware es suficiente para las líneas verticales normales. Si no queremos crear líneas punteadas (por ejemplo, por ejemplo), esta es la única respuesta que funcionaría correctamente.
Subin Sebastian
16
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="rectangle" >
    <stroke android:width="1dp" android:color="@color/white" />
    <size android:width="2dp" />
</shape>

Funciona para mi . Póngalo como fondo de vista con fill_parent o tamaño fijo en dp height

logcat
fuente
12

Se me ocurrió una solución diferente. La idea es rellenar el dibujo primero con el color que le gusta que sea la línea y luego llenar toda el área nuevamente con el color de fondo mientras se usa el relleno izquierdo o derecho. Obviamente, esto solo funciona para una línea vertical en el extremo izquierdo o derecho de su dibujo.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@color/divider_color" />
    <item android:left="6dp" android:drawable="@color/background_color" />
</layer-list>
Eric Kok
fuente
Necesitaba un fondo con bordes a la izquierda, derecha, abajo y esto funcionó para mí, ¡gracias!
Andrii Chernenko el
Impresionante, con esto logré crear divisores limpios en mi LinearLayout ( showDividers="middle"). Para obtener un divisor de 2dp, necesitaba especificar android:left="3dp"aquí.
Jonik
Consejo: para que este dibujo sea útil de manera más general, use en @android:color/transparentlugar de codificación fija @color/background_color.
Jonik
En realidad, para mis necesidades de divisor vertical, esta solución es aún más simple . :)
Jonik
@ Jonik Claro, pero eso solo funciona con una vista de altura fija, no con wrap_content.
Eric Kok
10

Creo que esta es la solución más simple:

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

    <item
        android:gravity="center">
        <shape android:shape="rectangle">
            <size android:width="1dp" />
            <solid android:color="#0000FF" />
        </shape>
    </item>

</layer-list>
a.ch.
fuente
Maravilloso. Agregue android:heighta sizesi desea controlar también esa dimensión.
Giulio Piancastelli
4

Necesitaba agregar mis vistas de forma dinámica / programática, por lo que agregar una vista adicional hubiera sido engorroso. La altura de mi vista era WRAP_CONTENT, por lo que no pude usar la solución rectangular. Encontré una publicación de blog aquí sobre extender TextView, anular onDraw () y pintar en la línea, así que implementé eso y funciona bien. Vea mi código a continuación:

public class NoteTextView extends TextView {
    public NoteTextView(Context context) {
       super(context);
    }
    private Paint paint = new Paint();
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        paint.setColor(Color.parseColor("#F00000FF"));
        paint.setStrokeWidth(0);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawLine(0, 0, 0, getHeight(), paint);
    }
}

Necesitaba una línea vertical a la izquierda, pero los parámetros de la línea de dibujo son drawLine(startX, startY, stopX, stopY, paint)para que pueda dibujar cualquier línea recta en cualquier dirección a través de la vista. Luego, en mi actividad, NoteTextView note = new NoteTextView(this); espero que esto ayude.

willlma
fuente
3

es muy simple ... agregar una línea vertical en android xml ...

<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:layout_marginTop="5dp"
android:rotation="90"
android:background="@android:color/darker_gray"/>
usuario3130068
fuente
Esto funciona muy bien cuando no puede usar fill_parent para la altura porque la altura principal está configurada en wrap_content.
Sergey Aldoukhov
2

Depende de dónde desea tener la línea vertical, pero si desea un borde vertical, por ejemplo, puede hacer que la vista principal tenga un fondo dibujable personalizado. Y luego puedes definir el dibujable de esta manera:

<?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:width="1dp" android:color="#000000" />
            <solid android:color="#00ffffff" />

        </shape>
    </item>

    <item android:right="1dp">
        <shape android:shape="rectangle">
            <solid android:color="#00ffffff" />
        </shape>
    </item>

</layer-list>

Este ejemplo creará una delgada línea negra delgada de 1dp en el lado derecho de la vista, que tendrá este dibujo como fondo.

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

    <item
        android:bottom="-3dp"
        android:left="-3dp"
        android:top="-3dp">

        <shape android:shape="rectangle">
            <solid android:color="@color/colorPrimary" />
            <stroke
                android:width="2dp"
                android:color="#1fc78c" />
        </shape>

    </item>

</layer-list>
AnupamChugh
fuente
2

Parece que nadie mencionó esta opción:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:drawable="@color/white" android:width="1dp"/>
</layer-list>
Sergey Neskoromny
fuente
1

Puedes usar una forma pero en lugar de una línea, hazla rectangular.

android:shape="rectangle">
<stroke
    android:width="5dp"
    android:color="#ff000000"
    android:dashGap="10px"
    android:dashWidth="30px" />

y en su diseño use esto ...

<ImageView
    android:layout_width="7dp"
    android:layout_height="match_parent"
    android:src="@drawable/dashline"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layerType="software"/>

Es posible que tenga que jugar con el ancho, dependiendo del tamaño de los guiones, para colocarlo en una sola línea.

Espero que esto ayude a Cheers

Boxlady
fuente
1
add this in your styles.xml

        <style name="Divider">
            <item name="android:layout_width">1dip</item>
            <item name="android:layout_height">match_parent</item>
            <item name="android:background">@color/divider_color</item>
        </style>

        <style name="Divider_invisible">
            <item name="android:layout_width">1dip</item>
            <item name="android:layout_height">match_parent</item>
        </style>

then wrap this style in a linear layout where you want the vertical line, I used the vertical line as a column divider in my table. 

     <TableLayout
                android:id="@+id/table"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:stretchColumns="*" >

                <TableRow
                    android:id="@+id/tableRow1"
                    android:layout_width="fill_parent"
                    android:layout_height="match_parent"
                    android:background="#92C94A" >

                    <TextView
                        android:id="@+id/textView11"
                        android:paddingBottom="10dp"
                        android:paddingLeft="5dp"
                        android:paddingRight="5dp"
                        android:paddingTop="10dp" />
    //...................................................................    

                    <LinearLayout
                        android:layout_width="1dp"
                        android:layout_height="match_parent" >

                        <View style="@style/Divider_invisible" />
                    </LinearLayout>
        //...................................................................
                    <TextView
                        android:id="@+id/textView12"
                        android:paddingBottom="10dp"
                        android:paddingLeft="5dp"
                        android:paddingRight="5dp"
                        android:paddingTop="10dp"
                        android:text="@string/main_wo_colon"
                        android:textColor="@color/white"
                        android:textSize="16sp" />
  //...............................................................  
                    <LinearLayout
                        android:layout_width="1dp"
                        android:layout_height="match_parent" >

                        <View style="@style/Divider" />
                    </LinearLayout>

    //...................................................................
                    <TextView
                        android:id="@+id/textView13"
                        android:paddingBottom="10dp"
                        android:paddingLeft="5dp"
                        android:paddingRight="5dp"
                        android:paddingTop="10dp"
                        android:text="@string/side_wo_colon"
                        android:textColor="@color/white"
                        android:textSize="16sp" />

                    <LinearLayout
                        android:layout_width="1dp"
                        android:layout_height="match_parent" >

                        <View style="@style/Divider" />
                    </LinearLayout>

                    <TextView
                        android:id="@+id/textView14"
                        android:paddingBottom="10dp"
                        android:paddingLeft="5dp"
                        android:paddingRight="5dp"
                        android:paddingTop="10dp"
                        android:text="@string/total"
                        android:textColor="@color/white"
                        android:textSize="16sp" />
                </TableRow>

                <!-- display this button in 3rd column via layout_column(zero based) -->

                <TableRow
                    android:id="@+id/tableRow2"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="#6F9C33" >

                    <TextView
                        android:id="@+id/textView21"
                        android:padding="5dp"
                        android:text="@string/servings"
                        android:textColor="@color/white"
                        android:textSize="16sp" />

                    <LinearLayout
                        android:layout_width="1dp"
                        android:layout_height="match_parent" >

                        <View style="@style/Divider" />
                    </LinearLayout>

    ..........
    .......
    ......
YasirAzgar
fuente
0

Para hacer una línea vertical, solo use un rectángulo con un ancho de 1dp:

<shape>
    <size
        android:width="1dp"
        android:height="16dp" />
    <solid
        android:color="#c8cdd2" />
</shape>

No use stroke, use solid(que es el color de "relleno") para especificar el color de la línea.

David Wasser
fuente
-1
 <View
        android:layout_width="2dp"
        android:layout_height="40dp"

        android:background="#ffffff"
        android:padding="10dp" />`
Surender Kumar
fuente