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

相关推荐
白云LDC1 小时前
Android Studio新建Vecter asset一直显示Loading icons(转圈圈)的解决办法
android·ide·android studio
Rytter4 小时前
某气骑士 libtprt.so 反 Frida 机制分析与绕过
android·安全·网络安全
alexhilton5 小时前
揭密:Compose应用如何做到启动提升34%
android·kotlin·android jetpack
沐言人生7 小时前
React Native 源码分析1——HybridData 机制深度分析
android·react native
程序员陆业聪8 小时前
跨平台框架全景图:Flutter/KMP/KuiKly/RN的2026年格局
android
码云数智-园园9 小时前
Fibers(纤程)来了:打破阻塞,实现纯PHP下的异步非阻塞IO
android
shaoming377611 小时前
检查系统硬件配置是否满足PyCharm最低要求
android·spring boot·mysql
一起搞IT吧12 小时前
高通Camx功能feature分析之十五:insensor zoom介绍及实现
android·智能手机·相机
aqi0013 小时前
一文读懂 HarmonyOS 6.1 带来的十大重要升级
android·华为·harmonyos·鸿蒙·harmony
秋915 小时前
MySQL 9.7.0 使用详解:新特性、实战与避坑指南
android·数据库·mysql