Linha vertical usando XML drawable

162

Estou tentando descobrir como definir uma linha vertical (1dp de espessura) para ser usada como um drawable.

Para fazer uma horizontal, é bem direto:

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

A questão é: como tornar essa linha vertical?

Sim, existem soluções alternativas, como desenhar um retângulo com 1px de espessura, mas isso complica o XML desenhável, se ele consiste em vários <item>elementos.

Alguém teve alguma chance com isso?

ATUALIZAR

O caso ainda não foi resolvido. No entanto, para qualquer pessoa em uma cruzada de documentação do Android - você pode achar útil: Manual XML XML ausente do Android

ATUALIZAR

Não encontrei outro caminho além do que marquei como correto. Ele faz o truque, embora pareça um pouco "pesado"; portanto, se você souber a resposta, não se esqueça de compartilhar;)

Kaspa
fonte

Respostas:

394

Em vez de uma forma, você pode tentar View:

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

Eu só usei isso para linhas horizontais, mas acho que funcionaria também para linhas verticais.

Usar:

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

para uma linha horizontal.

CommonsWare
fonte
4
obrigado Mark :)! Estou ciente de que posso usar uma visão para conseguir isso. O problema é que estou montando uma visão um pouco mais complexa que quero usar como um desenho para o fundo de uma célula da tabela. Existem diferentes tipos de formas / gradientes / linhas lá. Usar uma visualização seria uma solução, no entanto, eu teria que colocá-la em uma "camada" de desenho diferente e que está potencialmente disparando contra o seu pé quando eu me deparar com o redimensionamento, etc. shape "xmls, talvez alguém do google possa nos esclarecer? :)
Kaspa 17/04
1
Usar marginRight / Start e Left / End também às vezes é interessante para obter espaço nas laterais.
George
108

Você pode aninhar sua forma dentro de uma marca de rotação.

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

No entanto, o único problema é que os parâmetros de layout definidos no xml do layout serão as dimensões usadas para desenhar a forma original. Ou seja, se você deseja que sua linha tenha 30dp de altura, é necessário definir uma largura de layout de 30dp no seu xml de layout. Mas a largura final também será de 30dp nesse caso, o que provavelmente é indesejável para a maioria das situações. Essencialmente, isso significa que largura e altura devem ter o mesmo valor, o valor do comprimento desejado para a linha. Eu não conseguia descobrir como consertar isso.

Essa parece ser a solução "android way", mas, a menos que haja alguma correção ou solução alternativa para o problema de dimensões que mencionei, isso provavelmente não funcionará para a maioria das pessoas. O que realmente precisamos é de um atributo de orientação em <shape /> ou <stroke />.

Você também pode tentar referenciar outro drawable nos atributos da tag rotate, como:

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

No entanto, eu não testei isso e espero que ele tenha os mesmos problemas.

- EDITAR -

Oh, eu realmente descobri uma correção. Você pode usar uma margem negativa no xml do layout para se livrar do espaço extra indesejado. Tal 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
fonte
4
embora a margem negativa funcione para 99% dos dispositivos .... saiba que existem dispositivos por aí que serão forçados a fechar se você fizer isso. Alguns dispositivos têm dificuldade para inflar uma margem negativa
Kent Andersen
2
@cephus Eu uso seu primeiro código, mas preciso da linha no topo da visualização. Está no centro da minha opinião. Como posso definir uma gravidade para ele (dentro do arquivo xml da forma)?
Behzad
20

Você pode usar o atributo rotate

 <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>
user4679242
fonte
6
Essa é definitivamente uma resposta melhor (ou a melhor) porque, enquanto a resposta do @ commonsware é suficiente para linhas verticais normais. Se não quisermos criar linhas tracejadas (por exemplo), esta é a única resposta que funcionaria corretamente.
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 mim . Coloque-o como plano de fundo com fill_parent ou tamanho fixo em dp height

logcat
fonte
11

Eu vim com uma solução diferente. A idéia é preencher o desenho primeiro com a cor que você deseja que a linha seja e, em seguida, preencher toda a área com a cor de fundo enquanto usa o preenchimento esquerdo ou direito. Obviamente, isso só funciona para uma linha vertical na extrema esquerda ou direita do seu drawable.

<?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
fonte
Eu precisava de fundo com bordas à esquerda, direita, baixo e isso funcionou para mim, obrigado!
Andrii Chernenko
Impressionante, com isso eu consegui criar divisores elegantes em meu LinearLayout ( showDividers="middle"). Para obter um divisor 2dp, eu precisava especificar android:left="3dp"aqui.
Jonik
Dica: para tornar este extra útil útil de maneira mais geral, use em @android:color/transparentvez de codificar @color/background_color.
Jonik
Na verdade, para minhas necessidades de divisores verticais, essa solução é ainda mais simples . :)
Jonik
@ Jonik Claro, mas isso só funciona com uma vista de altura fixa, não com wrap_content.
22714 Eric Eric Kok
10

Eu acho que esta é a solução mais simples:

<?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.
fonte
Maravilhoso. Adicione android:heighta sizese você deseja controlar também essa dimensão.
Giulio Piancastelli
4

Eu precisava adicionar meus pontos de vista de forma dinâmica / programática, portanto, adicionar um ponto de vista extra teria sido complicado. A altura da minha vista era WRAP_CONTENT, então não pude usar a solução retangular. Eu encontrei um blog post aqui sobre como estender TextView, substituindo onDraw () e pintura na linha, então eu implementei isso e ele funciona bem. Veja meu código abaixo:

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);
    }
}

Eu precisava de uma linha vertical à esquerda, mas os parâmetros da drawLine(startX, startY, stopX, stopY, paint)linha de tração são para que você possa desenhar qualquer linha reta em qualquer direção da vista. Então, na minha atividade, NoteTextView note = new NoteTextView(this); espero que isso ajude.

willlma
fonte
3

é muito simples ... adicionar uma linha vertical no 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"/>
user3130068
fonte
Isso funciona muito bem quando você não pode usar fill_parent para height porque a altura pai está definida como wrap_content.
Sergey Aldoukhov 15/11
2

Depende de onde você deseja ter a linha vertical, mas se você quiser uma borda vertical, por exemplo, a visualização principal pode ter um plano de fundo que pode ser desenhado como um desenho personalizado. E você pode definir o drawable assim:

<?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 exemplo criará uma linha preta fina de 1dp no lado direito da vista, que terá esse desenho como plano de fundo.

Lukas1
fonte
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
fonte
2

Parece que ninguém mencionou esta opção:

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

Você pode usar uma forma, mas em vez de uma linha, retângulo.

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

e No seu layout, use isso ...

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

Talvez você precise brincar com a largura, dependendo do tamanho dos traços, para colocá-la em uma única linha.

Espero que isso ajude Felicidades

Boxlady
fonte
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
fonte
0

Para fazer uma linha vertical, basta usar um retângulo com largura de 1dp:

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

Não use stroke, use solid(que é a cor "preenchimento") para especificar a cor da linha.

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

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