如何在线性布局的一个侧面上绘制边框?

219

我可以给一个线性布局添加边框,但是它会被画在所有的边上。我希望只将其限制在右侧,就像在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
11个回答

391
您可以使用此方法在一个方向上获取边框。
<?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
如果你想要一个带有底部边框的实心Alpha颜色,你该怎么办?我一直在思考用Android Drawable XML API解决这个问题,但我想不出来。 - Mario Lenci
这对我没用--奇怪的是它做了相反的事情,使内部变得更暗,而我叠加在边框上的灰色渐变。一直在考虑制作一个特定大小的矩形可绘制对象,放置在项目的drawableLeft上。这似乎不太流畅。 - jbenowitz
@jbenowitz:layer-list 中项目的顺序非常重要。如果您反转,则会得到那些结果。 - Vivek Khandelwal
我已通过在边框颜色上添加描边,并保持按钮颜色的形状来解决了这个问题。这招很管用。 - jbenowitz

268

简单易懂,允许使用透明背景:

<?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 = 顶部

20
这是目前为止最好的答案,可惜没有被点赞。 - mittelmania
12
好的,我会尽力进行翻译。内容为:"Nice, however I certainly wouldn't describe it as "easy as pie"。" 可以翻译为:"不错,但我肯定不会把它形容为“轻而易举”的事情。" - funkybro
11
如果你需要更厚的边框或者需要在多个边上添加边框,那么这种方法就不适用。 - holographic-principle
1
@codeman - 使用此作为您视图的背景,那么它将继承其高度。 - Oded Breiner
2
如何调整描边或边框宽度? - Ruturaj Patil
显示剩余8条评论

112

你也可以使用单层实现你想要的内容。

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

通过这种方式,只有左边框是可见的,但是你可以通过调整item元素的bottomleftrighttop属性来实现任何你想要的组合。


4
当您具有其他背景颜色并希望在此可绘制背景上叠加边框时,这肯定是有用的。 (y) - Aung Pyae
3
正是我所需要的,但使用负边距是否正确? - IliaEremin
1
这是最好的解决方案。我在烦恼-5dp在那里有什么作用。 - Amit Kumar
1
负边距在HTML/CSS中很常见。它只是简单地将事物向另一个方向推动。根据我的经验,在Android中也似乎完全有效。 - spaaarky21
使用负边距实现的布局,如果您的clipChildren=false或clipToPadding=false,则效果不佳。如果是这种情况,您可以使用两个重叠的矩形解决方案,就像Vivek Khandelwal提出的那样。 - Jesús Barrera

107

为了让一个可绘制对象只有一侧有边框,可以将其他三个方向的 inset 设为负值 (使得这些边框被绘制到屏幕外)。

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

enter image description here

这种方法与naykah的答案类似,但不使用layer-list


5
在我看来,这是最好的答案。 - James
1
非常好的答案,我只需要将宽度和插入改为10dp :) 而且,我需要在左边加上边框,所以我将android:insetLeft更改为android:insetRight。如此简单!保持Material按钮点击:D - Phuong
正是我所需要的,只需在顶部更改“insertX”即可决定显示哪些边框和不显示哪些边框。 - CularBytes
4
注意:这将改变您所看到的内容并调整其大小。请谨慎使用。 - vovahost
这是最佳答案,因为它允许使用透明背景,并允许指定dp而不是采用将渐变压缩成一条线的技巧。 - F.K. Juliano
显示剩余3条评论

33

另一个很棒的例子example

<?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="#70b23f" />
         <solid android:color="@android:color/transparent" />
     </shape>
     
</inset>

1
到目前为止,这对我来说是最好的。 - Steven T.
1
这是我见过最可靠的答案。谢谢。 - Emin Turk

9

作为替代方案(如果您不想使用background),您可以通过创建如下视图来轻松实现:

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

想要只有左边框,请在布局(您想要有边框的位置)之前放置以下代码:

对我很有效...希望能对你有所帮助....


7
我用以下代码实现了这个效果。
<?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>

2
这里没有提到nine-patch文件。是的,您必须创建该文件,不过这是一项相当简单的工作,并且它是一个真正的“跨版本和透明度支持”的解决方案。如果将该文件放置在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>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接