当前位置: 移动技术网 > IT编程>移动开发>Android > Android开发学习之路--Kotlin之Android开发使用心得和注意事项

Android开发学习之路--Kotlin之Android开发使用心得和注意事项

2018年09月11日  | 移动技术网IT编程  | 我要评论

佛山电视台,海军司令员孙建国,执法记录仪zhifayihao

前言

1 @autowired需要@jvmfield注解




    

我们在activity的oncreate中就可以直接这么写

tv1.text = "hello kotlin" //textview填内容
bt1.setonclicklistener {  //监听button事件
    toast("hello kotlin")
}

但是如果是fragment中的话,需要注意一点就是:

不能在oncreateview方法里用view,不然会出现空指针异常,需要在onviewcreate里。因为kotlin的插件用了getview来findviewbyid,在onviewcreate后才获取到view.

3 with,apply

减少代码量,这个可以看下上一篇《 android开发学习之路–kotlin之常用表达式及函数》,这里不做过多介绍

4 fun内部也可以定义fun 利用局部函数抽取重复代码

可以在函数内部定义函数,来简化代码

比如一个findview的函数如下:

fun initview() {
    private var mtv1:textview = itemview.findviewbyid(r.id.tv_1) as textview
    private var mtv2:textview = itemview.findviewbyid(r.id.tv_2) as textview
    private var mtv3:textview = itemview.findviewbyid(r.id.tv_3) as textview
}

我们可以写一个内部函数,然后可以简化如下:

fun initview() {
    private fun findtextview(id: int) = itemview.findviewbyid(id) as textview

    private var mtv1 = findtextview(r.id.tv_1)
    private var mtv2 = findtextview(r.id.tv_2)
    private var mtv3 = findtextview(r.id.tv_3)
}

5 匿名内部类

kotlin中没有java的new关键字,所以在调用类似于监听的方法中的匿名内部类时候,需要用到object,如下所示

addontabselectedlistener(object : tablayout.ontabselectedlistener {
    override fun ontabreselected(tab: tablayout.tab?) {
    }

    override fun ontabunselected(tab: tablayout.tab?) {

    }

    override fun ontabselected(tab: tablayout.tab?) {

    }
})

6 代码注入 kapt

编译器的依赖关系需要使用kapt

kapt "com.google.dagger:dagger-compiler:$dagger_compiler_version"

7 static方法

在kotlin中使用类似java的静态方法,使用companion object

class utils {
    companion object {
        fun test() {
            toast("hello kotlin")
        }
    }
}

上述可以使用utils.test()来调用

8 单表达式函数

a+b,或者比大小的函数,可以写的很简单:

fun sum(a:int, b:int) = a+b 

9 使用数据类来快速实现model类

一般java中我们声明一个model类,需要设置属性为private,然后实现set/get方法,而kotlin中,我们只要简单地使用data就可以了。

//用data关键词来声明一个数据类,除了会自动实现get set,还会自动生成equals hashcode tostring
data class person(
    var name:string = "",
    var sex:string = "male"
)

若要实现parcelable,需要在builder.gradle中加入plugin

apply plugin: 'kotlin-android-extensions'

......

androidextensions {
    experimental = true
}

具体注解如下:

@parcelize
data class person(
    var name:string = "",
    var sex:string = "male"
): parcelable

10 lambda表达式简化onclicklistener

比如一个click事件
textview textview = new textview(context);
textview.setonclicklistener(new view.onclicklistener() {
    @override
    public void onclick(view v) {
        //do something
    }
});
lambda的方式
textview.setonclicklistener({ v ->
    {
        //do something
    }
})
当lambda的参数没有使用时可以省略,省略的时候用it来替代
textview.setonclicklistener({ 
    //do something
})
函数如果没有其他参数可以省略,最后变成了
textview.setonclicklistener {
   //do something 
}

11 高阶函数+lambda简化代码

当我们监听tablayout的select的时候,一般我们这么写:

tablayout.addontabselectedlistener(object : tablayout.ontabselectedlistener {
    override fun ontabreselected(tab: tablayout.tab?) {
         //do something
    }

    override fun ontabunselected(tab: tablayout.tab?) {
        //do something
    }

    override fun ontabselected(tab: tablayout.tab?) {
        //do something
    }
})

有时候我们只需要调用其中的一个方法,则显得代码臃肿。这个时候高阶函数和lambda就可以派上用场了。

首先我们实现一个类实现tablayout.ontabselectedlistener接口。然后定义三个函数,传入的参数分别是函数,然后当接口中的方法被回调后,再调用具体传入的函数的方法。

class _ontabselectedlistener : tablayout.ontabselectedlistener {
    private var _ontabreselected: ((tab: tablayout.tab?) -> unit)? = null
    private var _ontabunselected: ((tab: tablayout.tab?) -> unit)? = null
    private var _ontabselected: ((tab: tablayout.tab?) -> unit)? = null

    override fun ontabreselected(tab: tablayout.tab?) {
        _ontabreselected?.invoke(tab)
    }

    fun ontabreselected(func: (tab: tablayout.tab?) -> unit) {
        _ontabreselected = func
    }

    override fun ontabunselected(tab: tablayout.tab?) {
        _ontabunselected?.invoke(tab)
    }

    fun ontabunselected(func: (tab: tablayout.tab?) -> unit) {
        _ontabunselected = func
    }

    override fun ontabselected(tab: tablayout.tab?) {
        _ontabselected?.invoke(tab)
    }

    fun ontabselected(func: (tab: tablayout.tab?) -> unit) {
        _ontabselected = func
    }
}

然后我们写一个tablayout的扩展函数,入参是一个函数,是我们上面写好的这个类的函数,返回一个unit

fun tablayout.addontabselectedlistener(func: _ontabselectedlistener.() -> unit) {
    val listener = _ontabselectedlistener()
    listener.func()
    addontabselectedlistener(listener)
}

最后我们可以把代码写成这样:

addontabselectedlistener {
    ontabunselected {
        //do something
    }

    ontabselected {
        //do something
    }

    ontabreselected { 
        //do something
    }
}

当然,可以省略ontabunselected, ontabselected,ontabreselected的任何一个或者全部。

12 委托模式(by 关键字)

先定义两个接口base1和base2
interface base1 {
    fun print1()
}
interface base2 {
    fun print2()
}
两个实现类分别实现base1和base2
class baseimpl(val x: int) : base1 {
    override fun print1() {
        log.d("baseimpl", "print1 -> $x")
    }
}
class baseimpl2(val x: int) : base2 {
    override fun print2() {
        log.d("baseimpl", "print2 -> $x")
    }
}
接着用代理
class printtest(
        b1: base1,
        b2: base2
) : base1 by b1, base2 by b2
具体实现
val print1 = baseimpl(10)
val print2 = baseimpl2(5)
printtest(print1, print2).print1()
printtest(print1, print2).print2()

// 输出
d/baseimpl: print1 -> 10
d/baseimpl: print2 -> 5

printertest没有实现接口base1的方法print1(),而是通过关键字by,将实现委托给了b1。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网