Как нарисовать границу только на одной стороне линейного макета?


186

Я могу нарисовать границу для линейного макета, но он рисуется со всех сторон. Я хочу ограничить его только правой стороной, как вы делаете в CSS (border-right: 1px solid red;).

Я пробовал это, но это все еще привлекает все стороны:

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

Любые предложения о том, как это сделать?

КСТАТИ, я не хочу использовать взломать вид ширины 1dp с необходимой стороны.


вы можете использовать drawableLeft в вашем макете
njzk2

Ответы:


359

Вы можете использовать это, чтобы получить границу на одной стороне

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

отредактированный

Поскольку многие, в том числе и я, хотели иметь BorderDrawableодностороннюю границу с прозрачным фоном, я реализовал функцию, которая могла бы давать мне границы с разным размером и цветом так же, как мы используем CSS. Но это не может быть использовано через XML. Для поддержки XML, я добавил, BorderFrameLayoutчто ваш макет можно обернуть.

Смотрите мой GitHub для полного источника.


5
Что делать, если вам нужен сплошной альфа-цвет с нижней границей? Я думал о решении этого с API Android Drawable XML, но я не могу понять это.
Марио Ленчи

Это не сработало для меня - как ни странно, получилось обратное тому, что я хотел, чтобы внутри был более темный цвет, с серым градиентом, который я наложил на границы. Задумывались над тем, чтобы сделать прямоугольник рисованным с определенным размером, чтобы его можно было нарисовать как элемент drawableLeft. Это не кажется таким обтекаемым.
Джбеновиц

@jbenowitz: порядок элемента в списке слоев более важен. Если вы поменяете местами, вы получите такой результат.
Вивек Хандельвал

Я исправил это, добавив штрих цвет рамки и форму, оставшуюся от цвета кнопки. Это добилось цели.
Джбеновиц

243

Легко, как пирог, позволяя прозрачный BG:

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

Измените угол, чтобы изменить положение границы:

  • 0 = слева
  • 90 = низ
  • 180 = справа
  • 270 = верх

19
Это, безусловно, лучший ответ здесь, очень жаль, что это не проголосовало
mittelmania

11
Хорошо, но я бы не стал описывать это так просто, как пирог.
funkybro

7
Это не работает, если вам нужна более толстая граница или если вам нужны границы с нескольких сторон.
голографический принцип

1
@codeman - используйте это как фон для вашего вида, тогда он будет наследовать его высоту.
Одед Брейнер

2
Как настроить ширину обводки или границы?
Рутурадж Патил

101

также возможно реализовать то, что вы хотите, используя один слой

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

таким образом , только левая граница видна , но вы можете достичь любой комбинации вы хотите, играя с bottom, left, rightи topатрибуты itemэлемента


3
Это определенно полезно, когда у вас есть другой цвет фона, и вы хотите наложить эту рисованную полосу с границей. (у)
Аунг Пайе

3
Именно то, что мне нужно, но правильно ли использовать отрицательные отступы?
Илья Еремин

1
Это лучшее решение. Я беспокоюсь о том, что делает -5dp там.
Амит Кумар

1
Отрицательные отступы распространены в HTML / CSS. Это просто подталкивает вещи в другом направлении. По моему опыту, это выглядит совершенно справедливо и в Android.
spaaarky21

Реализации, использующие отрицательные поля, не работают хорошо, если ваш макет имеет clipChildren = false или clipToPadding = false. Если это так, вы можете использовать решение с двумя перекрывающимися прямоугольниками, как предложено Вивеком Хандельвалом
Хесусом Баррерой

80

Чтобы получить границу только с одной стороны отрисовки, примените отрицание insetк другим 3 сторонам (в результате чего эти границы будут нарисованы за пределами экрана).

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

введите описание изображения здесь

Этот подход похож на ответ Найки, но без использования a layer-list.


4
Это лучший ответ ИМО
Джеймс

очень хороший ответ, мне просто нужно изменить ширину и врезку на 10dp :) И еще, мне нужна граница слева, поэтому я меняю android: insetLeft на android: insetRight. Так просто! Нажатие кнопки «Удержание материала»: D
Phuong

Именно то, что мне было нужно, измените insertXсверху, чтобы решить, какие границы показывать, а какие нет.
CularBytes

У меня даже может быть сплошной цвет @null, и тогда этот метод не вызывает оверрейда. Genius. Спасибо!
Unknownweirdo

2
Внимание: это изменит содержание вашего представления, а также изменит его размер. Используйте с осторожностью.
vovahost

7

В качестве альтернативы (если вы не хотите использовать фон), вы можете легко сделать это, сделав вид следующим образом:

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

Чтобы иметь только правую границу, поместите ее после макета (где вы хотите иметь границу):

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

Чтобы иметь только левую границу, поместите ее перед макетом (там, где вы хотите иметь границу):

Работал на меня ... Надеюсь, это поможет ...


6

Я смог добиться эффекта с помощью следующего кода

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

Вы можете приспособиться к вашим потребностям в положении границы, изменив направление смещения


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>

5

Другой отличный пример пример

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

2

Здесь нет упоминаний о файлах с девятью патчами . Да, вам нужно создать файл, однако это довольно простая работа, и это действительно решение с поддержкой кросс-версии и прозрачности . Если файл помещен в drawable-nodpiкаталог, он работает на pxоснове, и вdrawable-mdpi работает примерно как база dp (благодаря повторной выборке).

Пример файла для исходного вопроса ( border-right: 1px solid red; ) находится здесь:

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

Просто поместите его в drawable-nodpiкаталог.


2

Границы разных цветов. Я использовал 3 предмета.

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