我爱编程

kotlin使用记录

2018-05-29  本文已影响207人  有点健忘

https://kotlinlang.org/docs/reference/android-overview.html
记录

let, also,apply,run

https://blog.csdn.net/u013064109/article/details/78786646
简单分析下,also和apply一样都是返回自己, let和run一样返回花括号代码块最后一行的返回值
另外一样的2种区别就在于代码块里用it还是this代替变量,而this可以省略不写。

image.png

如上图,结果就是 2个hello,以及7和5
简单看下源码

public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }

public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
public inline fun <T, R> T.run(block: T.() -> R): R = block()

看到源码可能感觉和我们的写法不一样。其实原因很简单,kotlin里一个函数可以作为参数的,完事这个函数可以写到括号外边。
比如 T.apply({//函数块}) 可以写成 T.apply(){//函数块}
对于let和run,如果要主动return一个东西,这样写的// return@run 333

在看demo的时候看到这些代码,扩展函数

可以注意到方法名字前有个xxx. 的东西,这个就是声明对哪个类进行扩展

/**
 * The `fragment` is added to the container view with id `frameId`. The operation is
 * performed by the `fragmentManager`.
 */
fun AppCompatActivity.replaceFragmentInActivity(fragment: Fragment, @IdRes frameId: Int) {
    supportFragmentManager.transact {
        replace(frameId, fragment)
    }
}

/**
 * The `fragment` is added to the container view with tag. The operation is
 * performed by the `fragmentManager`.
 */
fun AppCompatActivity.addFragmentToActivity(fragment: Fragment, tag: String) {
    supportFragmentManager.transact {
        add(fragment, tag)
    }
}

fun AppCompatActivity.setupActionBar(@IdRes toolbarId: Int, action: ActionBar.() -> Unit) {
    setSupportActionBar(findViewById(toolbarId))
    supportActionBar?.run {
        action()
    }
}

/**
 * Runs a FragmentTransaction, then calls commit().
 */
private inline fun FragmentManager.transact(action: FragmentTransaction.() -> Unit) {
    beginTransaction().apply {
        action()
    }.commit()
}

代码里这样用的

        setupActionBar(R.id.toolbar) {
            setHomeAsUpIndicator(R.drawable.ic_menu)
            setDisplayHomeAsUpEnabled(true)
        }

其实原本应该这样的,不过最后一个参数是一个函数的话,可以直接把括号的实现提到圆括号外面,就成了上边的写法了

        setupActionBar(R.id.toolbar, {
            setHomeAsUpIndicator(R.drawable.ic_menu)
            setDisplayHomeAsUpEnabled(true)
        })

when

java 中的switch 在kotlin里的写法,

when(xxx){
            is Int->{
            }
            in 0..10->{
            }
 1->{
}
2->{
}
3,4->{}
else->{}
}

2个方法互相引用的时候

java代码如下,我是2个runnable 互相调用

    private void starte(){
        handler.postDelayed(r1,1000);
    }
    Handler handler=new Handler();
    
    Runnable r1=new Runnable() {
        @Override
        public void run() {
            System.out.println("==========1");
            handler.postDelayed(r2,1111);
        }
    };
    
    Runnable r2=new Runnable() {
        @Override
        public void run() {
            System.out.println("==========2");
            handler.postDelayed(r1,1111);      
        }
    };

kotlin代码如下

    internal var handler = Handler()

    internal var r1: Runnable = Runnable {
        println("==========1")
        handler.postDelayed(r2, 1111)
    }

    internal var r2: Runnable = Runnable {
        println("==========2")
        handler.postDelayed(r1, 1111)
    }

    private fun starte() {
        handler.postDelayed(r1, 1000)
    }

看下转化,加了internal,这个是限定同一模块下可以访问,非必需。
关键有的地方 r2: Runnable 这个,2个Runnable必须有一个需要加冒号声明类型,否则就报错。
Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly
中文:类型检查遇到了递归问题。最简单的解决方法:显式地指定声明的类型。

可以看到上边都是简化后的写法了。如果这个时候要使用this,就不行了,得写完整的
如下

    internal var r2: Runnable = object : Runnable {
        override fun run() {
            println("==========2")
            handler.postDelayed(r1, 1111)
            handler.postDelayed(this, 2222)
            Runnable { handler.postDelayed(this, 2222) }.run()
        }
    }

循环的几种写法

下边的代码结果都一样,都是从0到4循环的,从大到小的话可以用 downto关键字

    private fun forTest(){
        //循环N次,from 0 start
        repeat(5){
            println("a============$it")
        }
        for(i in 0 ..4){
            println("b==========$i")
        }
        for(i in 0 until 5){
            println("c==========$i")
        }
        (0..4).forEach {
            println("d==============$it")
        }
    }

set get

//set的简化写法
     var tasks: List<Task> = tasks
            set(tasks) {
                field = tasks
                notifyDataSetChanged()
            }

  //get的简化写法
    override var isActive: Boolean = false
        get() = isAdded

thread ,简化写法如下,不需要start,内部默认构造方法里start为true的。

thread {

}

问题记录

1~
java 代码 Object obj=new Object(); obj.wait();
kotlin里的Any()对象没有wait()方法,不知道转成kotlin之后咋写。
解决办法,kt里继续new一个Object对象而不是any对象。
https://www.jianshu.com/p/3963e64e7fe7
2~
java代码的switch(index){
case 2:
if(index<10){
//xxxxxxxxxxx
break;
}
if(index<100){
//xxxxxxxxx
break;
}

//xxxxxxxxxx
break;
}
kotlin里没有break,这种半路很多break的难道只能用一堆if和else来写吗?

双冒号::

可以理解为把一个方法当对象处理,如下

    class A {
       lateinit var b:B
        init {
            b=B().apply {
                this.callbackA=this@A::testA//把testA这个方法传递给B里边的一个变量callbackA了
            }
        }
        fun testA(name: String,age:Int){

        }
    }
    class B{
        var callbackA:((String,Int) ->Unit)?=null//这里对应写出参数的类型,返回的类型好匹配,因为是可以为空的,所以括起来加个问号
        fun testB(){
            callbackA?.invoke("jerry",33)
        }
    }

上边的可以用来写我们平时用的Callback。
如果是java,我们一般是定义一个interface,完事定义一个interface的变量,然后用的时候实例化一个interface调用
然后看下改版后的写法
如下自定义的类

class ItemTouchListener{

//某个地方调用
singleTapCallback?.invoke(position,rv.getChildViewHolder(child))

//然后定义的回调
var singleTapCallback:((position: Int, viewHolder: RecyclerView.ViewHolder)->Unit)?=null
}

然后是正式使用的地方

        rv_temp.addOnItemTouchListener(ItemTouchListener(rv_temp).apply {
            singleTapCallback=this@FragmentTempTest::singleTab
//或者这样调用也可以
            singleTapCallback={position, viewHolder -> 
                
            }
        })

//这个就是我们的回调实现方法拉。
   fun singleTab(position: Int, viewHolder: RecyclerView.ViewHolder){

    }

这里还有一些
https://blog.csdn.net/lmo28021080/article/details/81505211

inline,noline

参考https://blog.csdn.net/Jaden_hool/article/details/78437947

上一篇 下一篇

猜你喜欢

热点阅读