android anko 插件,Android kotlin+anko自定义view进阶篇(二)

开篇

继上篇,本篇教你如何用 Kotlin+Anko 更简洁地自定义控件。假如我们需要定义效果如下的控件:

96841c97ca26

一个横向的LinearLayout包含三个子控件:ImageView、TextView、ImageView。

1、自定义控件,代码很简单,MyItemLayout.kt:

open class MyItemLayout : LinearLayout {

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()

}

private fun init() = apply{

orientation = LinearLayout.HORIZONTAL

gravity = Gravity.CENTER_VERTICAL

//icon

iconView = imageView(){

imageResource = R.drawable.kit_ic_assignment_blue_24dp

}

iconView.layoutParams = LayoutParams(wrapContent, wrapContent)

//label

labelView = textView {

textSize = 14f

textColor = 0xFF333333.toInt()

leftPadding = dip(12)

rightPadding = dip(12)

}

labelView.layoutParams = LayoutParams(0, wrapContent, 1.0f)

//arrow

arrowView = imageView(){

imageResource = R.drawable.kit_ic_chevron_right_gray_24dp

}

arrowView.layoutParams = LayoutParams(wrapContent, wrapContent)

}

fun getIconView(): ImageView {

return iconView

}

fun getLabelView(): TextView {

return labelView

}

fun getArrowView(): ImageView {

return arrowView

}

}

说明:

private lateinit var iconView: ImageView

private lateinit var labelView: TextView

private lateinit var arrowView: ImageView

我们并不希望外部使用者替换我们这三个view,所以都设置成private访问权限。又因为是lateinit属性,所以我们不能在属性下面添加get和set方法。如果要提供外部直接访问这三个view,我们自行添加get方法。

lateinit' modifier is not allowed on properties with a custom getter or setter

2、给MyItemLayout添加扩展内联方法,方便以Anko语法调用。MyItemLayoutExtend.kt:

import android.content.Context

import android.view.ViewManager

import android.widget.ImageView

import android.widget.TextView

import jsc.kit.itemlayout.MyItemLayout

import org.jetbrains.anko.custom.ankoView

import org.jetbrains.anko.internals.AnkoInternals

inline fun ViewManager.myItemLayout(

ctx: Context = AnkoInternals.getContext(this),

theme: Int = 0,

init: MyItemLayout.() -> Unit

): MyItemLayout {

return ankoView({ MyItemLayout(ctx) }, theme, init)

}

//icon

inline fun T.ilIcon(

init: ImageView.() -> Unit

): T {

getIconView().init()

return this

}

//label

inline fun T.ilLabel(

init: TextView.() -> Unit

): T {

getLabelView().init()

return this

}

//arrow

inline fun T.ilArrow(

init: ImageView.() -> Unit

): T {

getArrowView().init()

return this

}

说明:

inline fun ViewManager.myItemLayout(

ctx: Context = AnkoInternals.getContext(this),

theme: Int = 0,

init: MyItemLayout.() -> Unit

): MyItemLayout {

return ankoView({ MyItemLayout(ctx) }, theme, init)

}

ctx ——Context 。我们初始化为AnkoInternals.getContext(this)返回的值

theme—— Int。我们初始化为0

init—— block块。我们把block的作用域限制在MyItemLayout的对象内

如果非block参数有初始化值,在调用时可以不传

同理我们再来看看上面的ilLabel扩展:

inline fun T.ilLabel(

init: TextView.() -> Unit

): T {

getLabelView().init()

return this

}

我们只定义了一个参数initblock,其作用域是TextView,我们用来配置MyItemLayout中的labelView。

getLabelView().init()大概意思就是:让MyItemLayout中的labelView执行init这块代码。

我们可以这样写,让init没有作用域,仅仅是一个block块:

inline fun T.ilLabel(

init: () -> Unit

): T {

init()

return this

}

3、在Anko中使用MyItemLayout:

myItemLayout {

leftPadding = dip(16)

rightPadding = dip(16)

topPadding = dip(8)

bottomPadding = dip(8)

backgroundResource = R.drawable.xxx

}.ilIcon {

imageResource = R.drawable.xxx

}.ilLabel {

text = "I'am JustinEoy"

textColor = Color.BLUE

textSize = 15f

}.ilArrow {

imageResource= R.drawable.xxx

alpha = 0.4f

}

源码

篇尾

如果觉得我写得不错的点个爱心吧,也顺便加个关注啦!我是JustinRoom, QQ:10063682252。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值