Android kotlin+anko自定義view進(jìn)階篇(一)

下一篇: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é)KotlinAnko的示例石蔗,也是一個(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)的坡耘纱【炊牵”

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市束析,隨后出現(xiàn)的幾起案子艳馒,更是在濱河造成了極大的恐慌,老刑警劉巖员寇,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鹰溜,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡丁恭,警方通過查閱死者的電腦和手機(jī)曹动,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來牲览,“玉大人墓陈,你說我怎么就攤上這事〉谙祝” “怎么了贡必?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)庸毫。 經(jīng)常有香客問我仔拟,道長(zhǎng),這世上最難降的妖魔是什么飒赃? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任利花,我火速辦了婚禮科侈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘炒事。我一直安慰自己臀栈,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布挠乳。 她就那樣靜靜地躺著权薯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪睡扬。 梳的紋絲不亂的頭發(fā)上盟蚣,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音卖怜,去河邊找鬼屎开。 笑死,一個(gè)胖子當(dāng)著我的面吹牛韧涨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播侮繁,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼虑粥,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了宪哩?” 一聲冷哼從身側(cè)響起娩贷,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎锁孟,沒想到半個(gè)月后彬祖,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡品抽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年储笑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片圆恤。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡突倍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出盆昙,到底是詐尸還是另有隱情羽历,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布淡喜,位于F島的核電站秕磷,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏炼团。R本人自食惡果不足惜澎嚣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一疏尿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧币叹,春花似錦润歉、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至贩汉,卻和暖如春驱富,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背匹舞。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工褐鸥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赐稽。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓叫榕,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親姊舵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子晰绎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容