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,散会。

相关推荐
robotx1 天前
安卓线程相关
android
消失的旧时光-19431 天前
Android 面试高频:JSON 文件、大数据存储与断电安全(从原理到工程实践)
android·面试·json
dalancon1 天前
VSYNC 信号流程分析 (Android 14)
android
dalancon1 天前
VSYNC 信号完整流程2
android
dalancon1 天前
SurfaceFlinger 上帧后 releaseBuffer 完整流程分析
android
用户69371750013841 天前
不卷AI速度,我卷自己的从容——北京程序员手记
android·前端·人工智能
程序员Android1 天前
Android 刷新一帧流程trace拆解
android
墨狂之逸才1 天前
解决 Android/Gradle 编译报错:Comparison method violates its general contract!
android
阿明的小蝴蝶1 天前
记一次Gradle环境的编译问题与解决
android·前端·gradle
汪海游龙1 天前
开源项目 Trending AI 招募 Google Play 内测人员(12 名)
android·github