下一篇:kotlin+anko自定義view進(jìn)階篇(二)
開篇
??我最近在學(xué)習(xí)Kotlin+Anko組合開發(fā)Android App借浊。如何用Kotlin+Anko自定義控件,網(wǎng)上的資料不但少萝招,而且還很凌亂蚂斤。經(jīng)過一段時(shí)間的摸索我大概掌握了這娘們的脾氣了。今天就教童鞋們?nèi)绾斡?strong>Kotlin+Anko自定義控件槐沼。
效果圖
實(shí)現(xiàn)
- 1曙蒸、kotlin自定義view(橫向排列三個(gè)控件:ImageView、TextView岗钩、ImageView):JSCItemLayout.kt
class JSCItemLayout : FrameLayout, IBaseView {
//私有成員
private lateinit var iconView: ImageView
private lateinit var labelView: TextView
private lateinit var arrowView: ImageView
constructor(context: Context) : this(context, null)
constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
//init(context)要在retrieveAttributes(attrs)前調(diào)用
//因?yàn)閷傩再x值纽窟,會(huì)直接賦值到控件上去。如:
//調(diào)用label = ""時(shí)兼吓,相當(dāng)于調(diào)用了label的set方法臂港。
init(context)
//retrieveAttributes(attrs: AttributeSet)方法只接受非空參數(shù)
attrs?.let { retrieveAttributes(attrs) }
}
override fun init(context: Context) {
}
override fun retrieveAttributes(attrs: AttributeSet) {
}
}
我抽象出來一個(gè)接口:IBaseView.kt
interface IBaseView {
//用來初始化view視圖
fun init(context: Context)
//用來接收xml文件中的自定義屬性
fun retrieveAttributes(attrs: AttributeSet)
}
- 2、實(shí)現(xiàn)
init(context: Context)
方法:
override fun init(context: Context) {
val layout = LinearLayout(context)
layout.orientation = LinearLayout.HORIZONTAL
layout.gravity = Gravity.CENTER_VERTICAL
addView(layout, LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT))
iconView = ImageView(context)
layout.addView(iconView, LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT))
labelView = TextView(context)
labelView.leftPadding = dip(12)
labelView.rightPadding = dip(12)
labelView.maxLines = 1
layout.addView(labelView, LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 1f))
arrowView = ImageView(context)
layout.addView(arrowView, LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT))
}
此時(shí)視圖已經(jīng)創(chuàng)建完了视搏,只是現(xiàn)在所有的視圖控件都是系統(tǒng)默認(rèn)屬性审孽。
- 3、添加自定義屬性
attr.xml
<declare-styleable name="JSCItemLayout">
<attr name="icon" format="reference" />
<attr name="label" format="string" />
<attr name="label_text_size" format="float" />
<attr name="label_text_color" format="color" />
<attr name="arrow_icon" format="reference" />
</declare-styleable>
在JSCItemLayout.kt中聲明屬性字段浑娜,并在各個(gè)屬性的set()方法中添加屬性到相應(yīng)的控件上去瓷胧。
@DrawableRes
var icon: Int = 0
set(value) {
field = value
iconView.imageResource = value
}
var label: CharSequence? = null
set(value) {
field = value
labelView.text = value
}
var labelTextSize: Float = 0f
set(value) {
if (value > 0) {
field = value
labelView.textSize = value
}
}
@ColorInt
var labelTextColor: Int = 0
set(value) {
field = value
labelView.textColor = value
}
@DrawableRes
var arrowIcon: Int = 0
set(value) {
field = value
arrowView.imageResource = value
}
到了這里,完全可以以kotlin語法調(diào)用constructor(context: Context)
創(chuàng)建控件并使用棚愤。For example:
var itemLayout = JSCItemLayout(context)
itemLayout.label = "label"
itemLayout.labelTextColor = 0xff333333.toInt()
...
如果想在xml中使用并有預(yù)覽效果搓萧,這還不夠杂数,我們需要實(shí)現(xiàn)retrieveAttributes(attrs: AttributeSet)
方法。
override fun retrieveAttributes(attrs: AttributeSet) {
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.JSCItemLayout)
val v1 = typedArray.getResourceId(R.styleable.JSCItemLayout_icon, 0)
if (v1 != 0)
icon = v1
label = typedArray.getText(R.styleable.JSCItemLayout_label)
labelTextSize = typedArray.getFloat(R.styleable.JSCItemLayout_label_text_size, 14f)
labelTextColor = typedArray.getColor(R.styleable.JSCItemLayout_label_text_color, 0xff333333.toInt())
val v2 = typedArray.getResourceId(R.styleable.JSCItemLayout_arrow_icon, 0)
if (v2 != 0)
arrowIcon = v2
typedArray.recycle()
}
ok瘸洛,到此揍移,自定義控件已經(jīng)完成了。接下來我們要如何在Anko和xml中使用反肋。
使用
- 1那伐、在Anko中使用:
聲明控件(我們可以專門建一個(gè)kt文件來管理我們自定的view):RegisteredComponents.kt
inline fun ViewManager.jscItemLayout() = jscItemLayout {}
inline fun ViewManager.jscItemLayout(theme: Int = 0, init: JSCItemLayout.() -> Unit): JSCItemLayout {
return ankoView({ JSCItemLayout(it) }, theme, init)
}
Anko調(diào)用:
jscItemLayout {
icon = R.drawable.xxx
label = "JSCItemLayout"
labelTextColor = Color.Blue
labelTextSize = 16f
arrowIcon = R.drawable.xxx
//其他屬性
...
}
- 2、在xml布局文件中使用:
<jsc.kit.itemlayout.JSCItemLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:icon="@drawable/xxx"
app:arrow_icon="@drawable/xxx"
app:label="label"
app:label_text_color="#FF00FF"
app:label_text_size="15" />
源碼
這里是我自學(xué)Kotlin和Anko的示例石蔗,也是一個(gè)簡(jiǎn)單的App框架罕邀,后期我們會(huì)慢慢完善這個(gè)示例框架。感謝童鞋們的多多關(guān)注养距!
示例傳送門————https://github.com/JustinRoom/MyKotlinAnko
篇尾
??一個(gè)人摸索不容易诉探,你的愛心和關(guān)注是我堅(jiān)持的動(dòng)力!QQ1006368252
棍厌。
巴菲特說肾胯,“人生就像滾雪球。重要的是發(fā)現(xiàn)很濕的雪和很長(zhǎng)的坡耘纱【炊牵”