Вертикальная линия с использованием XML Drawable


162

Я пытаюсь выяснить, как определить вертикальную линию (толщиной 1 дп), которая будет использоваться как рисование.

Чтобы сделать горизонтальный, это довольно просто:

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

Вопрос в том, как сделать эту линию вертикальной?

Да, есть обходные пути, такие как рисование прямоугольника в форме толщиной 1 пиксель, но это усложняет прорисовываемый XML, если он состоит из нескольких <item>элементов.

У кого-нибудь был шанс с этим?

ОБНОВИТЬ

Дело до сих пор не раскрыто. Тем не менее, для тех, кто участвует в крестовом походе по документации Android - вам может пригодиться это: Отсутствует руководство по XML для Android

ОБНОВИТЬ

Я не нашел другого пути, кроме того, который я отметил как правильный. Это делает трюк, хотя кажется немного "тяжелым", поэтому, если вам случится знать ответ, не забудьте поделиться;)

Ответы:


394

Вместо формы вы можете попробовать View:

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

Я использовал это только для горизонтальных линий, но я думаю, что это будет работать и для вертикальных линий.

Использование:

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

для горизонтальной линии.


4
спасибо Марк :)! Я знаю, что могу использовать вид, чтобы достичь этого. Дело в том, что я собираю немного более сложное представление, которое хочу использовать в качестве рисованного для фона ячейки таблицы. Там есть разные типы фигур / градиентов / линий. Использование вида БЫЛО было бы решением, однако мне пришлось бы поместить его в другой «слой» чертежа, и это может привести к попаданию в ногу, когда я столкнусь с изменением размера и т. Д. Интересно, почему нет документации по « shape "xmls, может быть, кто-то из Google может просветить нас? :)
Каспа

1
Использование marginRight / Start и Left / End также иногда интересно, чтобы получить место по бокам.
Джордж

108

Вы можете вкладывать свою форму в тег поворота.

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

Однако единственная проблема заключается в том, что параметры макета, определенные в макете XML, будут размерами, используемыми для рисования исходной фигуры. Это означает, что если вы хотите, чтобы ваша строка была 30dp высотой, вам нужно определить layout_width 30dp в вашем макете xml. Но конечная ширина также будет 30dp в этом случае, что, вероятно, нежелательно для большинства ситуаций. По сути, это означает, что ширина и высота должны быть одним и тем же значением, значением желаемой длины линии. Я не мог понять, как это исправить.

Похоже, это решение «android way», но если я не упомяну о каком-либо исправлении или обходном пути к проблеме размеров, то, скорее всего, это не сработает для большинства людей. Что нам действительно нужно, так это атрибут ориентации в <shape /> или <stroke />.

Вы также можете попробовать сослаться на другой объект рисования в атрибутах тега поворота, например:

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

Однако я не проверял это и ожидаю, что у него будут те же проблемы.

-- РЕДАКТИРОВАТЬ --

О, я действительно нашел решение Вы можете использовать отрицательную границу в своем макете XML, чтобы избавиться от нежелательного дополнительного пространства. Такие как:

<ImageView
    android:layout_width="35dp"
    android:layout_height="35dp"
    android:layout_marginLeft="-15dp"
    android:layout_marginRight="-15dp"
    android:src="@drawable/dashed_vertical_line" />

4
в то время как отрицательное поле будет работать для 99% устройств .... просто знайте, есть устройства, которые принудительно закроют, если вы сделаете это. Некоторые устройства имеют проблемы с накачиванием отрицательного поля
Кент Андерсен

2
@cephus Я использую твой первый код, но мне нужна строка сверху представления. Это в центре моего зрения. Как я могу установить гравитацию для него (внутри XML-файла формы)?
Бехзад

20

Вы можете использовать атрибут поворота

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

6
Это определенно лучший (или лучший) ответ, потому что, хотя ответа @ commonsware достаточно для нормальных вертикальных линий. Если мы не хотим создавать пунктирные линии (скажем, например), это единственный ответ, который будет работать правильно.
Субин Себастьян

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>

Работает для меня . Поместите это как фон представления с fill_parent или фиксированным размером в высоту dp


12

Я придумал другое решение. Идея состоит в том, чтобы сначала заполнить нарисованное цветом того цвета, который вам нравится, а затем снова заполнить всю область цветом фона, используя отступы влево или вправо. Очевидно, что это работает только для вертикальной линии в крайнем левом или правом углу вашей карты.

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

Мне нужен фон с границами слева, справа, снизу, и это сработало для меня, спасибо!
Андрей Черненко

Удивительно, с этим мне удалось создать аккуратные разделители в моем LinearLayout ( showDividers="middle"). Чтобы получить 2dp делитель, мне нужно было указать android:left="3dp"здесь.
Йоник

Совет: чтобы сделать это рисование более полезным, используйте @android:color/transparentвместо жесткого кодирования @color/background_color.
Йоник

На самом деле для моих потребностей вертикального делителя это решение еще проще . :)
Jonik

@Jonik Конечно, но это работает только с фиксированной высоты, а не с wrap_content.
Эрик Кок

10

Я думаю, что это самое простое решение:

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

Чудесно. Добавить android:heightк , sizeесли вы хотите контролировать также , что измерение.
Джулио

4

Мне нужно было добавлять свои представления динамически / программно, поэтому добавление дополнительного представления было бы обременительным. Высота моего вида была WRAP_CONTENT, поэтому я не мог использовать прямоугольное решение. Я нашел записи блога здесь о расширении TextView, перекрывая OnDraw () и живописи в линии, так что я осуществил это , и это хорошо работает. Смотрите мой код ниже:

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

Мне нужна вертикальная линия слева, но параметры линии рисования таковы, drawLine(startX, startY, stopX, stopY, paint)что вы можете нарисовать любую прямую линию в любом направлении поперек вида. Тогда в моей деятельности я NoteTextView note = new NoteTextView(this); надеюсь, что это помогает.


3

это очень просто ... добавить вертикальную линию в 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"/>

Это прекрасно работает, когда вы не можете использовать fill_parent для высоты, потому что родительская высота установлена ​​в wrap_content.
Сергей Алдоухов

2

Зависит от того, где вы хотите иметь вертикальную линию, но если вы хотите, например, вертикальную границу, у родительского вида может быть фон, который можно нарисовать по своему усмотрению. И тогда вы можете определить рисование следующим образом:

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

В этом примере будет создана тонкая черная линия с разрешением 1 дп с правой стороны вида, которая будет отображаться в качестве фона.


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>

2

Похоже, никто не упомянул эту опцию:

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

1

Вы можете использовать форму, но вместо линии сделать ее прямоугольником.

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

и в вашем макете используйте это ...

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

Возможно, вам придется поиграть с шириной, в зависимости от размера штрихов, чтобы вывести ее в одну строку.

Надеюсь, что это помогает Ура


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>

    ..........
    .......
    ......

0

Чтобы сделать вертикальную линию, просто используйте прямоугольник шириной 1 дп:

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

Не используйте stroke, используйте solid(который является цветом «заливки»), чтобы указать цвет линии.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.