关于 Kotlin 自定义 View 时,引用系统属性问题

时间:2022-07-02 20:09:37

这两天在写项目进行组合自定义一个项目中频繁使用的组件时,需要一些属性,比如 text , textSize , textColor 等等,由于所需要的属性,基本上系统都有了,我这里就想偷个懒直接拿过来用,但是事与愿违,并没有使用成功。因为时间原因,就还是去老老实实的添加自定义属性去了,趁着这个礼拜天,再来调试一下(控件继承于 RelativeLayout)。

使用 Java 代码去借用系统属性的写法如下:

private static final int[] ATTRS = new int[]{android.R.attr.textSize,
            android.R.attr.textColor};
···
        TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);

        tabTextSize = a.getDimensionPixelSize(0, tabTextSize);
        tabTextColor = a.getColor(1, tabTextColor);

        a.recycle();

这是之前 Java 语言的写法,是可以调用成功的,即使有多个属性,也没问题。
但是在 Kotlin 中,同样的写法,

    private val systemText = intArrayOf(
            android.R.attr.text,
            android.R.attr.textSize
    )
    ...
        val types = context.obtainStyledAttributes(attrs, systemText)
        textStr = types.getString(0)
        textSize = types.getInt(1, textSize)
        types.recycle()

这种写法得到的结果是 textStr 正常获取,textSize 为默认值,也就是获取失败。
难道是类型问题?那么换个其他的 String,Drawable 等类型,都是行不通的。调试过程中, types 的长度也是对的。但是就是不知道为什么获取不到这个属性值。
因为只能获取到第一个,所以我把所有需要的属性给拆分为一个为一组去获取。代码如下:

    private val systemDrawPadding = intArrayOf(
            android.R.attr.drawablePadding
    )
    private val systemDrawLeft = intArrayOf(
            android.R.attr.drawableLeft
    )
    private val systemText = intArrayOf(
            android.R.attr.text
    )
    private val systemTextSize = intArrayOf(
            android.R.attr.textSize
    )

    init {
        var types = context.obtainStyledAttributes(attrs, systemDrawPadding)
        drawPadding = types.getDimensionPixelOffset(0, drawPadding)
        types.recycle()

        types = context.obtainStyledAttributes(attrs, systemDrawLeft)
        leftDraw = types.getDrawable(0)
        types.recycle()

        types = context.obtainStyledAttributes(attrs, systemText)
        textStr = types.getString(0)
        types.recycle()

        types = context.obtainStyledAttributes(attrs, systemTextSize)
        size = types.getDimensionPixelSize(0, size)

        types.recycle()
    }

这样的写法,每一个系统属性又都能获取到了。留下了一脸懵逼的我~
如果真的只能这样去获取系统属性值的话,我觉得我们还是直接去自定义吧。



至于为什么不能同时添加多个系统属性的问题,目前还在求解中。如果哪位大佬知道原因,还望指点迷津~