How to create vertical dashed line divider using xml in Android?

这篇文章讨论一个问题:Android开发中,如何实现界面上显示分隔线。

The topic here is how to create dashed line divider on screen in Android.

如果是实线,问题就很简单了,直接用View,设置背景就ok。但是如果设计稿里面是虚线呢?答案大概有三种:1. 请设计师出图;2. 自定义View绘制;3. 使用xml定义ShapeDrawable。

It is easy if the requirement is not dashed line, and the solution is just View with background color. But the dream can not always come true… the answer for the dashed line can be almost these three: 1. ask resource from the UI designer; 2. drawing with custom views; 3. create ShapeDrawable with xml.

再升级一下难度,如果是垂直分隔线呢?可能大部分同学就只剩前两个选择了。但是用xml,也是可以实现的,下面给大家分享这个小技巧。

To be more exciting, let’s replace the line with a vertical one. How to deal with it then? Probably the ahead 2 choices left with most guys. But the 3rd one is also available and this is what I want to share with you today.

首先看一下要怎么实现水平的虚分割线:

First of all let’s look at how to create a horizontal dashed line:

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

&lt;stroke
    android:width="1dp"
    android:color="@color/divider"
    android:dashWidth="2dp"
    android:dashGap="1dp"/&gt;

</shape>
So easy是不是,下面好戏上场,垂直分割线:

It is easy just like it looks. But there comes the kill part —- vertical divider:

<?xml version=”1.0” encoding=”utf-8”?>
<layer-list xmlns:android=”http://schemas.android.com/apk/res/android"&gt;
<item
android:left=”-300dp”
android:right=”-300dp”>
<rotate
android:drawable=”@drawable/dash_line_divider_horizontal”
android:fromDegrees=”90”
android:toDegrees=”90”
android:visible=”true”/>
</item>
</layer-list>

看到这里,大家是不是已经懂了?关键的有这么几点:

You get me! And these is the key point:

  1. 使用rotate标签让水平分割线旋转90度,变成垂直。但是单纯旋转还是不够的,因为分割线的尺寸会受到View边界的限制,如果View的大小为W1dp*H24dp,那么虚线的长度只有1dp,旋转后也是看不到的,下面是解决方法。
  2. 使用layer-list,扩展Drawable的尺寸。通过指定left和right的属性为负值,可以让layer的边界超过View的边界。还是刚才的场景,虚线的长度就是601dp,这样旋转过来,就可以显示了。
  3. 上面设置的left和right属性,要设置成绝对值一致,因为旋转的锚点是中心点,如果不对称,旋转之后依然看不到虚线。

  1. Using rotate tag to rotate the divider with 90 degrees to vertical. But this is not enough, because its size is limited by the bounds of view. If the View is 1dp width and 24dp height, then the line’s length is just 1dp and this is not enough to make it visible after rotate. Following is the solution.
  2. Extend the drawable’s size with layer-list by assigning the left and right properties with negative value beyond the view’s bounds. The length of line becomes 601dp under the same situation above and this make it visible.
  3. The absolute values of that 2 properties have to be the same. Only if this can make it work because the anchor of rotating was at the center of view.
    知道原理之后,也可稍微发挥一下,比如这样:

You can make things more interesting after you got the principle, like this:

preview

Demo的完整代码,欢迎访问Github

The whole project is waiting for you at Github.

One more thing,在xml中使用虚线的时候,需要在使用的地方,把View的layerType设置为software,否则看到的是实现。

One more thing. When using dashed line in xml, make the value of layerType of target View be ‘software’, nor you would see solid line.

That’s it,have fun everyone.