这两天在写项目进行组合自定义一个项目中频繁使用的组件时,需要一些属性,比如 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;
}
...
获取相关属性之后,我们再去进行相应的设置。