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

这两天在写项目进行组合自定义一个项目中频繁使用的组件时,需要一些属性,比如 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()
    }

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



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

更新

上面遗留的关于借用系统属性自定义问题,这里再次整理一下。
在上面代码中,借用系统属性是直接在 View 中引用,这里进行调整一下,我们需要在 attrs 文件中进行直接引用


<declare-styleable name="CustomView">
    <attr name="android:textColor" />
    <attr name="android:textColorHint" />
    <attr name="android:hint" />
    <attr name="android:singleLine" />
    <attr name="android:inputType" />
    ...
</declare-styleable>

然后,我们在进行获取这些相关属性时,可以去参照系统的实现(也就是直接去相关控件中 copy 代码),比如 TextView 中:

...
swith(attrs){
    case com.android.internal.R.styleable.TextView_password:
        password = a.getBoolean(attr, password);
        break;
       ...
    case com.android.internal.R.styleable.TextView_drawableLeft:
         drawableLeft = a.getDrawable(attr);
         break;
}
...

获取相关属性之后,我们再去进行相应的设置。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值