AppCompat-LinearLayoutCompat分隔符/线还可以这么画?

话说,搬砖是一个体力活。在别人的代码里面总会发现一些知识点盲区里面的东西。今天搬砖过程中,发现之前代码的xml里面在局部的使用 LinearLayoutCompat。这玩意画出来的竟然和LinearLayout一样,emmmm?图啥?

ok,那么就直接上官网查看文档。 LinearLayoutCompat

将其子级排列在单列或单行中的布局。可以通过调用设置行的方向setOrientation()。您还可以指定gravity,它通过调用指定所有子元素的对齐方式,或者通过设置 的weight 成员setGravity()来指定特定子元素增长以填充布局中的任何剩余空间。默认方向是水平的。LinearLayoutCompat.LayoutParams 请参阅线性布局指南。

OK。这玩意就是LinearLayout 好吧,但是属性的时候发现了一个新的东西。divider 分割器。这就让我想到了一个界面效果:

正文

既然是LinearLayout,那么使用上就没有多少可以描述的了。我们直接整分隔符。

divider

通过官方文档我们可以看到,这个其实是由3个属性控制的,一个控制分隔符的样子,一个控制分隔符的间距,一个控制分隔符的显示效果。

showDividers

用于控制分割线的显示方式:

ini 复制代码
<attr name="showDividers">
    <flag name="none" value="0"/>
    <flag name="beginning" value="1"/>
    <flag name="middle" value="2"/>
    <flag name="end" value="4"/>
</attr>
  • none 不显示
  • beginning 显示在linearLayout 第一个view之前
  • middle 显示在linearLayout 每一个一级view之间
  • end 显示在linearLayout 最后一个view之后

dividerPadding

ini 复制代码
<attr format="dimension" name="dividerPadding"/>

设置分割线的的间距,比如说整个LinearLayout 是横向的那么就是上下间距。如果是纵向的就是左右间距。默认是0。

divider

这个是分割线的Drawable 对象。

ini 复制代码
<attr format="reference" name="divider"/>

ok,贼简单。一眼就会了,当我把下面的shape 设置进去的时候,却发现分隔符没有显示。emmmmm?

ini 复制代码
<?xml version="1.0" encoding="utf-8"?
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <solid android:color="#f00" />
</shape>

那么我们就来看为什么?

ini 复制代码
 Drawable divider=a.getDrawable(R.styleable.LinearLayoutCompat_divider)
 

下面是获取Drawable的代码:可以看到官方很多地方获取资源都是已经换成了AppCompat了。

aidl 复制代码
    public Drawable getDrawable(int index) {
        if (mWrapped.hasValue(index)) {
            final int resourceId = mWrapped.getResourceId(index, 0);
            if (resourceId != 0) {
                return AppCompatResources.getDrawable(mContext, resourceId);
            }
        }
        return mWrapped.getDrawable(index);
    }

下面是对于divider 进行解析。

ini 复制代码
public void setDividerDrawable(Drawable divider) {
    if (divider == mDivider) {
        return;
    }
    mDivider = divider;
    if (divider != null) {
        mDividerWidth = divider.getIntrinsicWidth();
        mDividerHeight = divider.getIntrinsicHeight();
    } else {
        mDividerWidth = 0;
        mDividerHeight = 0;
    }
    setWillNotDraw(divider == null);
    requestLayout();
}

然后随便找一个绘制分隔符的代码:

scss 复制代码
void drawHorizontalDivider(Canvas canvas, int top) {
    mDivider.setBounds(getPaddingLeft() + mDividerPadding, top,
            getWidth() - getPaddingRight() - mDividerPadding, top + mDividerHeight);
    mDivider.draw(canvas);
}

可以看到mDividerWidth和mDividerHeight起了关键点的作用。而上面的shape 获取到的都是0,所以说就无法显示。那么下面就可以显示了。

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <solid android:color="#00BCD4" />
    <size android:width="10dp" android:height="10dp"/>
</shape>

同理,svg,或者png等图片当可以获取到宽高的时候,就尅显示出来。

结束

其实,这个还是有点遗留问题。

遗留问题 :shape="line"作为分隔符不显示

ini 复制代码
<shape xmlns:android="http://schemas.android.com/apk/res/android"
 android:shape="line">
 <stroke android:width="1dp" android:color="#f00"/>
 <size android:height="10dp"></size>
</shape>

shape 包含了的样式蛮多的,可以都去试试。

demo 样式及其代码

时间有限,画的蛮丑的,将就一下,主要是代码功能逻辑。代码地址

OK,散会。

相关推荐
zh_xuan1 小时前
kotlin Channel的用法
android·kotlin·协程·channel
zh_xuan1 小时前
kotlin Flow的用法
android·开发语言·kotlin·协程·flow
普通网友7 小时前
Android Jetpack 架构组件最佳实践之“网抑云”APP
android·架构·android jetpack
普通网友7 小时前
原创_Android Jetpack Compose 最全上手指南
android·android jetpack
FDoubleman7 小时前
Android Jetpack之Compose入门(一)
android·android jetpack
普通网友7 小时前
Android Jetpack从入门到精通,干货满满
android·android jetpack
子云心7 小时前
Android Jetpack 系列(七)App Startup 启动优化
android·android jetpack·jetpack·initializer·startup·appstartup
嫩嫩的猿7 小时前
android jetpack compose Model对象更新变量 UI不更新、不刷新问题
android·ui·android jetpack
普通网友7 小时前
Android Jetpack 之 LifeCycle 组件_android 自定义view lifecycle
android·gitee·android jetpack