有没有一种简单的方法可以在 Android 视图的顶部和底部添加边框?

Posted

技术标签:

【中文标题】有没有一种简单的方法可以在 Android 视图的顶部和底部添加边框?【英文标题】:Is there an easy way to add a border to the top and bottom of an Android View? 【发布时间】:2010-12-08 13:26:55 【问题描述】:

我有一个 TextView,我想在它的顶部和底部边框上添加一个黑色边框。我尝试将android:drawableTopandroid:drawableBottom 添加到TextView,但这只会导致整个视图变黑。

<TextView
    android:background="@android:color/green"
    android:layout_
    android:layout_
    android:drawableTop="@android:color/black"
    android:drawableBottom="@android:color/black"
    android:text="la la la" />

有没有一种方法可以轻松地为 Android 中的 View(特别是 TextView)添加顶部和底部边框?

【问题讨论】:

令人惊讶的是没有人提到 dividerVertical !这是 Android 创建的东西,用于实现垂直分隔线。再简单不过了,您可以在 Android Studio 的“设计”所见即所得面板中完成所有操作。 note dividerVertical 在 API 11 中实现。 也许你可以展示如何使用dividerVertical? 【参考方案1】:

在 android 2.2 中,您可以执行以下操作。

创建一个 xml 可绘制对象,例如 /res/drawable/textlines.xml 并将其指定为 TextView 的背景属性。

<TextView
android:text="My text with lines above and below"
android:background="@drawable/textlines"
/>

/res/drawable/textlines.xml

<?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: android:color="#FF000000" />
            <solid android:color="#FFDDDDDD" />

        </shape>
   </item>

   <item android:top="1dp" android:bottom="1dp"> 
      <shape 
        android:shape="rectangle">
            <stroke android: android:color="#FFDDDDDD" />
            <solid android:color="#00000000" />
        </shape>
   </item>

</layer-list>

这样做的缺点是您必须指定不透明的背景颜色,因为透明胶片不起作用。 (至少我认为他们做到了,但我错了)。在上面的示例中,您可以看到第一个形状#FFdddddd 的纯色被复制到第二个形状的笔触颜色中。

【讨论】:

如果你想要一个边框,也可以看看这个解决方案,它也适用于 TextViews:***.com/questions/3263611/… 尝试使用android:color="@null" 来避免背景不透明的问题。 @emmby : 在平板电脑上测试这段代码时,在屏幕上渲染需要时间,1 秒后我滚动时会显示边框 android:color="@null" 技巧对我来说并没有起到保持透明度和仅在视图一侧显示边框的作用。下面 user1051892 的回答完成了这项工作! 这个解决方案在左右两边也做了一个边框——虽然更薄了。【参考方案2】:

我使用了一个技巧,使边框显示在容器外。有了这个技巧,只画了一条线,因此底层视图的背景将显示出来。

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:bottom="1dp"
        android:left="-2dp"
        android:right="-2dp"
        android:top="-2dp">
        <shape android:shape="rectangle" >
            <stroke
                android:
                android:color="#FF000000" />

            <solid android:color="#00FFFFFF" />

            <padding android:left="10dp"
                android:right="10dp"
                android:top="10dp"
                android:bottom="10dp" />
        </shape>
    </item>

</layer-list>

【讨论】:

这对我来说效果很好,通过一些调整使线条更细。 非常好的技巧,虽然如果我们不必为了完成任务而欺骗计算机,它可能会更好。 干得好!你应该看的是项目的左、上、右、下应该 -(stroke's width)dp 没有显示任何边框 - 只是让我的视图内容看起来更小:( 做得很好,使用透明背景。在 2.2 和 4.4.2 中测试。应该涵盖两者之间的所有内容:)【参考方案3】:

要仅在底部添加1dp 白色边框并具有透明背景,您可以使用以下内容,这比此处的大多数答案更简单。

对于TextView或其他视图添加:

android:background="@drawable/borderbottom"

并在drawable目录中添加以下XML,称为borderbottom.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:top="-2dp" android:left="-2dp" android:right="-2dp">
        <shape android:shape="rectangle">
            <stroke android: android:color="#ffffffff" />
            <solid android:color="#00000000" />
        </shape>
    </item>
</layer-list>

如果您想要顶部有边框,请将android:top="-2dp" 更改为android:bottom="-2dp"

颜色不需要是白色,背景也不需要是透明的。

solid 元素可能不是必需的。这将取决于您的设计(感谢 V. Kalyuzhnyu)。

基本上,此 XML 将使用矩形形状创建边框,然后将顶部、右侧和左侧推到形状的渲染区域之外。这只会让底部边框可见。

【讨论】:

这是最好的解决方案,因为它不会像其他人那样造成透支 是否有理由认为负位置是中风的两倍(-2dp vs 1dp)?当它们的数量相等时似乎有效(-11)。 @DenisKniazhev : 当使用-2dp 时,结果总是干净的。我认为存在结果不干净的测试用例。我不记得它是低密度屏幕还是高密度屏幕,甚至是旧版本的 Android(可能是 2.x)。 有趣。你知道这是否是一般情况,例如如果我使用4dp 作为笔划宽度,我应该使用-8dp 进行定位吗? @DenisKniazhev :(从记忆中)它看起来像一个浮点计算,只是有点大或小。这意味着-5dp 的值将是所有需要的宽度值4pd。它只需要稍微大一点就可以克服浮点值的不准确性。【参考方案4】:

选项 1:可绘制形状

如果您希望在可以设置背景的布局或视图周围设置边框,这是最简单的选项。在drawable 文件夹中创建一个如下所示的 XML 文件:

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

    <solid android:color="#8fff93" />

    <stroke
        android:
        android:color="#000" />

</shape>

如果您不想填充,可以删除 solid。在您的布局/视图上设置background="@drawable/your_shape_drawable"

选项 2:背景视图

这是我在RelativeLayout 中使用的一个小技巧。基本上,在要给边框的视图下方有一个黑色方块,然后给该视图一些填充(不是边距!),以便黑色方块在边缘显示出来。

显然,这只有在视图没有任何透明区域时才能正常工作。如果是这样,我建议您编写一个自定义的 BorderView,它只绘制边框 - 它应该只有几十行代码。

<View
    android:id="@+id/border"
    android:layout_
    android:layout_
    android:layout_alignBottom="@+id/image"
    android:layout_alignLeft="@+id/image"
    android:layout_alignRight="@+id/image"
    android:layout_alignTop="@+id/main_image"
    android:background="#000" />

<ImageView
    android:id="@+id/image"
    android:layout_
    android:layout_
    android:layout_...
    android:padding="1px"
    android:src="@drawable/..." />

如果您想知道,它确实适用于adjustViewBounds=true。但是,如果您想在整个RelativeLayout 中拥有背景,则它不起作用,因为有一个错误会阻止您用View 填充RelativeLayout。在这种情况下,我会推荐 Shape drawable。

选项 3:9 补丁

最后一种选择是使用像这样的 9-patch 可绘制对象:

您可以在可以设置android:background="@drawable/..." 的任何视图上使用它。是的,它确实需要是 6x6 - 我尝试了 5x5,但它不起作用。

这种方法的缺点是你不能很容易地改变颜色,但如果你想要花哨的边框(例如,只有顶部和底部的边框,就像这个问题一样)那么你可能无法做到Shape drawable,不是很强大。

选项 4:额外观看次数

如果您只想要视图上方和下方的边框,我忘了提及这个非常简单的选项。你可以把你的视图放在一个垂直的LinearLayout(如果还没有的话),然后像这样在它的上方和下方添加空的Views:

<View android:background="#000" android:layout_ android:layout_/>

【讨论】:

9 补丁和可绘制的形状都可以,但我建议不要添加视图或图像视图来解决此类问题。原因是您应该从布局中删除尽可能多的此类 以改进布局重绘和动画。我会立即去掉这些并实现一些类似于选项 1 或 2 的内容。 @Emile 没错,但如果您使用的是不支持分隔线的自定义 ListView,那么简单的 View 就可以了。性能影响几乎为零,特别是如果您确定要降低布局深度。它还规避了跨设备的 ListView 分隔符的错误(我见过一些忽略此属性的设备)。 您还可以将高效的视图模式与列表视图一起使用,以确保减少对 findViewByID 的调用次数,这通常是导致列表性能不佳的原因。 ios 中,您只有一种方法可以做到这一点。在 android 上,您应该至少测试四个,在我的情况下,选项 4 是要走的路。有时drawables作为背景挂起渲染,请注意。 为什么android没有最简单的解决方案?与其他语言一样,如 html、CSS 或 JavaFX、WPF……【参考方案5】:

当前接受的答案不起作用。由于抗锯齿,它会在视图的左侧和右侧创建细的垂直边框。

这个版本完美运行。它还允许您独立设置边框宽度,您还可以根据需要在左侧/右侧添加边框。唯一的缺点是它不支持透明度。

使用下面的代码创建一个名为 /res/drawable/top_bottom_borders.xml 的 xml 可绘制对象,并将其分配为 TextView 的背景属性。

<?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="#DDDD00" /> <!-- border color -->
        </shape>
    </item>

    <item
        android:bottom="1dp" 
        android:top="1dp">   <!-- adjust borders width here -->
        <shape android:shape="rectangle">
            <solid android:color="#FFFFFF" />  <!-- background color -->
        </shape>
    </item>
</layer-list>

通过 Marshmallow 在 Android KitKat 上测试

【讨论】:

如何使里面透明? @HiteshSahu 我认为这样做的缺点是您必须将布局的背景与此处的小部件背景相匹配【参考方案6】:

所以我想做一些稍微不同的事情:仅底部的边框,以模拟 ListView 分隔线。我修改了 Piet Delport 的答案并得到了这个:

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

        </shape>
   </item>

    <!-- this mess is what we have to do to get a bottom border only. -->
   <item android:top="-2dp"
         android:left="-2dp"
         android:right="-2dp"
         android:bottom="1px"> 
      <shape 
        android:shape="rectangle">    
            <stroke android: android:color="@color/background_trans_mid" />
            <solid android:color="@null" />
        </shape>
   </item>

</layer-list>

注意使用 px 而不是 dp 来获得正好 1 个像素的分隔线(某些手机 DPI 会使 1dp 线消失)。

【讨论】:

亲爱的! "@color/background_trans_light" 的值是多少? 干杯@phreakhead,这实际上对我有用!没有顶部、左侧或右侧边框。正是我需要的,谢谢! 请你解释一下为什么当你放 -2dp 时它消失了,而当你放 -1dp 时它仍然可见?谢谢! @phreakhead 如果您对此添加一些解释会更好【参考方案7】:

正如@Nic Hubbard 所说,有一种非常简单的方法可以添加边框线。

<View
    android:layout_
    android:layout_
    android:background="#000000" >
</View>

您可以将高度和背景颜色更改为任何您想要的。

【讨论】:

【参考方案8】:

将文件添加到 res/drawable

<?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:left="-2dp" android:right="-2dp">
            <shape android:shape="rectangle">
                <stroke
                    android:
                    android:color="#000000" />
            </shape>
        </item>
    </layer-list>

将此文件上的链接添加到背景属性

【讨论】:

【参考方案9】:

您还可以将视图包装在 FrameLayout 中,然后将框架的背景颜色和填充设置为您想要的;但是,默认情况下,textview 具有“透明”背景,因此您也需要更改 textview 的背景颜色。

【讨论】:

很简单。您可以通过内部视图的边距控制轮廓的大小和方向。谢谢。【参考方案10】:

我的答案基于@Emile 版本,但我使用透明色而不是纯色。 此示例将绘制 2dp 底部边框。

<?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:
                     android:color="#50C0E9" />
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
    <item  android:bottom="2dp" >
        <shape android:shape="rectangle" >
            <stroke  android:
                     android:color="@color/bgcolor" />
            <solid android:color="@android:color/transparent" />
        </shape>
    </item>
</layer-list>

@color/bgcolor 是您在其上绘制带边框的视图的背景颜色。

如果要更改边框的位置,请使用以下之一更改偏移量:

android:bottom="2dp"
android:top="2dp"
android:right="2dp"
android:left="2dp"

或将它们组合成 2 个或更多边框:

android:bottom="2dp" android:top="2dp"

【讨论】:

【参考方案11】:

为什么不直接创建一个带有背景颜色的 1dp 高视图?然后它可以很容易地放在你想要的地方。

【讨论】:

【参考方案12】:

要改变这个:

<TextView
    android:text="My text"
    android:background="@drawable/top_bottom_border"/>

我更喜欢“drawable/top_bottom_border.xml”中的这种方法:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <gradient
                android:angle="270"
                android:startColor="#000"
                android:centerColor="@android:color/transparent"
                android:centerX="0.01" />
        </shape>
    </item>
    <item>
        <shape>
            <gradient
                android:angle="90"
                android:startColor="#000"
                android:centerColor="@android:color/transparent"
                android:centerX="0.01" />
        </shape>
    </item>
</layer-list>

这只会制作边框,而不是在背景有颜色时出现的矩形。

【讨论】:

【参考方案13】:

使用InsetDrawable添加边框以插入边框的最简单方法,以下将仅显示顶部边框:

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetBottom="-2dp"
    android:insetLeft="-2dp"
    android:insetRight="-2dp">
    <shape android:shape="rectangle">

        <solid android:color="@color/light_gray" />
        <stroke
            android:
            android:color="@color/dark_gray" />
    </shape>
</inset>

【讨论】:

【参考方案14】:

只是将我的解决方案添加到列表中..

我想要一个延伸到原始形状之外的半透明底部边框(因此半透明边框在父矩形之外)。

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
  <item>
    <shape android:shape="rectangle" >      
      <solid android:color="#33000000" /> <!-- Border colour -->
    </shape>
  </item>
  <item  android:bottom="2dp" >
    <shape android:shape="rectangle" >     
      <solid android:color="#164586" />
    </shape>
  </item>
</layer-list>

这给了我;

【讨论】:

【参考方案15】:

首先制作一个xml文件,内容如下图,命名为border.xml,放到res目录下的layout文件夹中

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke android: android:color="#0000" />
    <padding android:left="0dp" android:top="1dp" android:right="0dp"
        android:bottom="1dp" />
</shape>

之后在代码里面使用

TextView tv = (TextView)findElementById(R.id.yourTextView);
tv.setBackgroundResource(R.layout.border);

这将在 TextView 的顶部和底部形成一条黑线。

【讨论】:

是的,它会工作,我已经检查过了。 Button button= (Button) findViewById(R.id.button); button.setBackgroundResource(R.layout.border); 我在上面的xml文件中使用了黑色,你的背景颜色可能是黑色,尝试使用其他颜色。它肯定会工作 schemas.android.com/apk/res/android"> 对我不起作用。边框线画在文本视图的中间 - 水平。【参考方案16】:

只需在View的顶部和底部添加Views

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_
    android:layout_>

    <View
        android:layout_
        android:layout_
        android:background="@color/your_color"
        app:layout_constraintBottom_toTopOf="@+id/textView"
        app:layout_constraintEnd_toEndOf="@+id/textView"
        app:layout_constraintStart_toStartOf="@+id/textView" />

    <TextView
        android:id="@+id/textView"
        android:layout_
        android:layout_
        android:layout_marginTop="32dp"
        android:gravity="center"
        android:text="Testing"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <View
        android:layout_
        android:layout_
        android:background="@color/your_color"
        app:layout_constraintEnd_toEndOf="@+id/textView"
        app:layout_constraintStart_toStartOf="@+id/textView"
        app:layout_constraintTop_toBottomOf="@+id/textView" />

</android.support.constraint.ConstraintLayout>

【讨论】:

【参考方案17】:

你可以通过这个代码sn-p来做到这一点-

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!--Minus (-) how much dp you gave in the stroke width from left right-->
    <item android:left="-10dp" android:right="-10dp">
        <shape
            android:shape="rectangle">
            <stroke android: android:color="@android:color/holo_red_dark" />
           <!--This is the main background -->
            <solid android:color="#FFDDDDDD" />
        </shape>
    </item>
</layer-list>

预览 -

【讨论】:

【参考方案18】:

写下下面的代码

<View
    android:layout_
    android:layout_
    android:layout_below="@+id/topics_text"
    android:layout_marginTop="7dp"
    android:layout_margin="10dp"
    android:background="#ffffff" />

【讨论】:

【参考方案19】:

尝试使用线性布局包裹图像,并将其背景设置为文本周围所需的边框颜色。然后将 textview 上的填充设置为您想要的边框厚度。

【讨论】:

【参考方案20】:

您还可以使用 9 路径来完成您的工作。创建它,使彩色像素的高度不会增加,而只会增加透明像素。

【讨论】:

【参考方案21】:
// Just simply add border around the image view or view

<ImageView
                android:id="@+id/imageView2"
                android:layout_
                android:layout_
                android:layout_centerVertical="true"
                android:layout_marginRight="10dp"
                android:layout_toLeftOf="@+id/imageView1"
                android:background="@android:color/white"
                android:padding="5dip" />

// After that dynamically put color into your view or image view object

objView.setBackgroundColor(Color.GREEN);

//VinodJ/Abhishek

【讨论】:

【参考方案22】:
<shape xmlns:android="http://schemas.android.com/apk/res/android">

<solid android:color="@color/light_grey1" />
<stroke
    android:
    android:color="@color/light_grey1" />

<corners
    android:bottomLeftRadius="0dp"
    android:bottomRightRadius="0dp"
    android:topLeftRadius="5dp"
    android:topRightRadius="5dp" />

    </shape>

【讨论】:

【参考方案23】:
<TextView
    android:id="@+id/textView3"
    android:layout_
    android:layout_
    android:background="#72cdf4"
    android:text=" aa" />

只需在要添加边框的文本下方添加此 TextView

【讨论】:

【参考方案24】:

只是为了强制执行@phreakhead ´s 和user1051892 ´s 答案,&lt;item android:bottom|android:left|android:right|android:top&gt; 如果是否定的,则必须大于&lt;stroke android:width&gt;。否则,item 的绘画将与 stroke 的绘画混合在一起,您可能会认为这些值不起作用。

【讨论】:

以上是关于有没有一种简单的方法可以在 Android 视图的顶部和底部添加边框?的主要内容,如果未能解决你的问题,请参考以下文章

将视图恢复到原始 xml 状态

如何在 Android 应用程序中阻止或改善横向视图

有没有一种简单的方法可以从 CakePHP 的视图中获取 AuthComponent 用户数据?

有没有一种简单的方法可以在 Android 上展平 json:api 响应?

有没有一种简单的方法可以知道在将 ContentObserver 用于 android 联系人时更改了哪个联系人?

如何在视图内的特定位置触发 Android Lollipop 的涟漪效应,而不触发触摸事件?