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

相关推荐
TimeFine41 分钟前
AI 编码工作流的设计
android·ai编程
骑着蜗牛撵大象3271 小时前
C++20 协程 × 屏障:手写一个 co_await 版 Barrier,让等待不再钉死线程
android·c++20·协程·并发编程·co_await·屏障同步
山东孙燕姿3 小时前
设备台账重构:从一张表到三层模型
android·java·网络·低代码·重构·rxjava
蒸鱼Yuzheng4 小时前
移动端 CPU 调度分析:线程亲和性、大小核迁移与卡顿
android·perfetto·性能分析·线程优化·cpu调度
booboosui4 小时前
安卓唤醒词:12 维 MFCC 加 DTW,阈值 1.8
android
传奇开心果4 小时前
Compose Multiplatform 共享边界实战:架构契约、互操作同步与可回退设计
android·kotlin
事圆则缓4 小时前
从开机到首帧:Android 系统与应用启动流程源码分析
android
AI吃大瓜5 小时前
指针压力表读数4:Android实现指针压力表读数(可实时检测)
android·指针读数·指针压力表·压力表·压力表读数
fengci.5 小时前
CTF2刷题记录(困难部分)
android·开发语言·前端·学习·php
hunterandroid5 小时前
[Android 从零到一] ARouter 路由框架原理:APT 生成路由表与组件化通信
android