重新定义分割线Drawable的Bounds
首先,需要清楚一个事实:出现以上情况的矛盾点,是官方ListView的分割线属性不支持左右留白。所以最佳的解决方案,就是使得官方的分割线支持这种功能,这样既利于扩展,也利于提高性能。
先来简单看一下,ListView的源码是如何实现分割线的功能的。
<code class="hljs java has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> drawDivider(Canvas canvas, Rect bounds, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> childIndex) { <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// This widget draws the same divider for all children</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> Drawable divider = mDivider; divider.setBounds(bounds); divider.draw(canvas); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
在onDraw方法中,最终会调用到drawDivider方法。由于分割线是一个Drawable对象,上下左右的位置都是由Rect对象控制的,这个对象通过setBounds方法设置。
这个Rect对象的top和bottom属性我们是不需要关心的,只需要看left和right两个属性,默认情况下left=paddingLeft,right=width-paddingLeft-paddingRight,即表示分割线的起点和终点贯穿ListView的左右两侧。
dispatchDraw方法中可以验证这一点:
<code class="hljs r has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> protected void dispatchDraw(Canvas canvas) { <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (drawDividers || drawOverscrollHeader || drawOverscrollFooter) { final Rect bounds = mTempRect; bounds.left = mPaddingLeft; bounds.right = mRight - mLeft - mPaddingRight; <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span> drawDivider(canvas, bounds, i); } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">...</span> }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>
如果我们能将bounds的left和right属性的值进行修改,那么就能实现控制分割线的左右边距了。
既然需要扩展ListView,最常用的方法就是继承重写了。不幸的是由于drawDivider方法的访问控制故并不能被复写,但值得庆幸的是ListView的Divider对象具有setter和getter方法。
具体的实现逻辑非常简单,核心是装饰模式,我就不去详细说了。
源码和范例详见:https://github.com/MegatronKing/DividerSample
用法非常简单,给ListView分割线扩充了两个属性:dividerPaddingLeft和dividerPaddingRight,顾名思义。这两个属性值既可以在xml布局中配置也可以在代码中设置。
layout示例如下:
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">com</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.megatronking</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.divider</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.view</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.DividerListView</span> xmlns:android=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://schemas.android.com/apk/res/android"</span> xmlns:divider=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://schemas.android.com/apk/res-auto"</span> android:id=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"@+id/list"</span> android:layout_width=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"match_parent"</span> android:layout_height=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wrap_content"</span> android:divider=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"#99cccccc"</span> android:dividerHeight=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"0.5dip"</span> divider:dividerPaddingLeft=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"15dip"</span> divider:dividerPaddingRight=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"15dip"</span> /></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>
使用inset标签定义drawable
在Drawable家族中有一个特殊的存在:InsetDrawable,可以定义上下左右四个边界的留白,InsetDrawable同样使用了装饰模式,和方案4的机制有异曲同工之妙。当被装饰Drawable的Bound值变化时,重新定义Bound。另外,最强大的是可以直接使用xml定义。
<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">inset</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:android</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:insetLeft</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"15dip"</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">shape</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">size</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"0.5dip"</span> /></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">solid</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:color</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"#99cccccc"</span> /></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">shape</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">inset</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>
通过insetLeft、insetRight、insetTop、insetRight四个属性可以定义不同方向的留白大小,另外还支持通过android:drawable熟悉引用另外一个Drawable即被装饰的Drawable。
2、LinearLayout的分割线
LinearLayout从Android 3.0版本开始,便添加了分割线属性。LinearLayout的分割线功能比ListView要强大一些,无论是横向线性布局还是纵向线性布局,都能够很好的支持。为了兼容3.0以下版本,v7包中提供一个LinearLayoutCompat布局,用法类似。
然而,知道这些属性的开发者并不多,很多时候还是使用着一条线一个View的方式。这种方式无疑使用繁琐,布局冗余。
现在先来简单介绍下LinearLayout的分割线功能。
LinearLayout的提供了三个分割线相关属性:
1、divider 必须引用一个drawable,无法使用或引用color。drawable一般是定义成shape,通过size指定宽度或高度,solid指定颜色。另外,由于LinearLayout分为横向布局和纵向布局,所以一般会定义两种分割线。
<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">shape</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:android</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"http://schemas.android.com/apk/res/android"</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">size</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:height</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"0.5dip"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">solid</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:color</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"#99cccccc"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">shape</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
<code class="hljs xml has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">shape</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">xmlns:android</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"http://schemas.android.com/apk/res/android"</span>></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">size</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:width</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"0.5dip"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"><<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">solid</span> <span class="hljs-attribute" style="box-sizing: border-box; color: rgb(102, 0, 102);">android:color</span>=<span class="hljs-value" style="box-sizing: border-box; color: rgb(0, 136, 0);">"#99cccccc"</span>/></span> <span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;"></<span class="hljs-title" style="box-sizing: border-box; color: rgb(0, 0, 136);">shape</span>></span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
2、dividerPadding 控制分割线的留白距离,相比于ListView分割线的通栏,这个属性非常实用。但是却有一个缺陷:dividerPadding无法指定左右或上下,横向布局中上下都会有留白,纵向布局中,左右都会有留白。而,设计师往往喜欢左侧留白右侧通栏,所以这个属性有时就非常尴尬。
3、showDividers 这个属性是控制分割线显示位置的,一共有四个值:middle 在每一项中间添加分割线;end 在整体的最后一项添加分割线;beginning 在整体的最上方添加分割线;none 无;如果不设置这个属性的值,默认就是none,即不显示分割线。
虽然LinearLayout的分割线功能非常强大,但是遇到一侧留白的情况,还是无能为力。开发者还是要回到使用View作为分割线的老路上来,比如QQ浏览器的这种布局:
分割线左侧留白与文字对齐,右侧通栏,dividerPadding这个属性实在无能为力!
在分析解决方案之前,来简单看一下分割线的实现原理吧!
<code class="hljs scss has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> void <span class="hljs-function" style="box-sizing: border-box;">drawHorizontalDivider(Canvas canvas, int top)</span> { mDivider<span class="hljs-class" style="box-sizing: border-box;">.setBounds</span>(<span class="hljs-function" style="box-sizing: border-box;">getPaddingLeft()</span> + mDividerPadding, <span class="hljs-attribute" style="box-sizing: border-box;">top</span>, <span class="hljs-function" style="box-sizing: border-box;">getWidth()</span> - <span class="hljs-function" style="box-sizing: border-box;">getPaddingRight()</span> - mDividerPadding, <span class="hljs-attribute" style="box-sizing: border-box;">top</span> + mDividerHeight); mDivider<span class="hljs-class" style="box-sizing: border-box;">.draw</span>(<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">canvas</span>); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>
<code class="hljs scss has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"> void <span class="hljs-function" style="box-sizing: border-box;">drawVerticalDivider(Canvas canvas, int left)</span> { mDivider<span class="hljs-class" style="box-sizing: border-box;">.setBounds</span>(<span class="hljs-attribute" style="box-sizing: border-box;">left</span>, <span class="hljs-function" style="box-sizing: border-box;">getPaddingTop()</span> + mDividerPadding, <span class="hljs-attribute" style="box-sizing: border-box;">left</span> + mDividerWidth, <span class="hljs-function" style="box-sizing: border-box;">getHeight()</span> - <span class="hljs-function" style="box-sizing: border-box;">getPaddingBottom()</span> - mDividerPadding); mDivider<span class="hljs-class" style="box-sizing: border-box;">.draw</span>(<span class="hljs-tag" style="color: rgb(0, 102, 102); box-sizing: border-box;">canvas</span>); }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li></ul>
一个水平方向的分割线,一个是垂直方向的分割线。同样是通过setBounds方法确定分割线的位置,而且mDividerPadding属性会同时作用于左右或上下。
所以,解决方案和前面所讲的ListView的应该是完全一样的:重新定义分割线Drawable的Bounds
源码不细说了,详见:https://github.com/MegatronKing/DividerSample
扩展LinearLayout提供了分割线的额外四个属性:dividerPaddingLeft,dividerPaddingRight,dividerPaddingTop,dividerPaddingBottom。同样的,既可以在layout中配置也可以在代码中动态设置。
当orientation为vertical时,dividerPaddingLeft和dividerPaddingRight两个属性生效;orientation为horizontal时,dividerPaddingTop和dividerPaddingBottom两个属性生效。
layout示例如下:
<code class="hljs avrasm has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">com</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.megatronking</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.divider</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.view</span><span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">.DividerLinearLayout</span> xmlns:android=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://schemas.android.com/apk/res/android"</span> xmlns:divider=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"http://schemas.android.com/apk/res-auto"</span> android:layout_width=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"match_parent"</span> android:layout_height=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"wrap_content"</span> android:divider=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"@drawable/line_horizontal"</span> android:orientation=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"vertical"</span> android:showDividers=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"middle"</span> divider:dividerPaddingLeft=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"15dip"</span>/></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li></ul>
当然,通过InsetDrawable方式同样可以达到效果,原理其实差不多,不再赘述。