Kotlin优雅地设计lambda接口参数

Stars-one 2020年07月22日 258次浏览 本篇字数为0字

本文为作者原创,转载请注明出处,谢谢配合
作者:Stars-one
链接:https://stars-one.site/2020/07/22/kotlin优雅地设计lambda接口参数


在Android开发中,我们经常使用setOnClickListener方法来设置点击事件,相对于以往的调用,我们可以发现,Kotlin的写法比较简洁,而且是使用的lambda表达式,如下

btn.setOnClickListener{
	...	
}

这样的方法是如何设计的呢?

接口参数

在这里,不得不提一下接口类型参数,Kotlin中,提供了接口类型的参数。我们在定义方法的时候可以使用这个参数,之后调用方法的时候即可使用lambda方式传递一个函数回调的函数过来

简单起见,我打算设计一个下载完毕回调的接口来说明

首先,介绍一下接口参数的格式,如(()->Unit),表明lambda表达式的参数为空,而且,没有返回值,就如之前setOnClickListener一样

下面这是lambda表达式的参数类型为String,返回值也为String,((text:String)->String)

下载完毕回调实现

我们设计一个下载类Downloader,其中有个startDownload的方法,用来从url下载文件,当然,方法里只是通过打印字符串来简单地模拟下载的过程

class Downloader{

    fun startDownload(url:String,downloadFinishListener:(()->Unit)){
        println("下载文件地址为$url")
        println("下载中...")
		//回调接口
		downloadListener.invoke()
    }
}

调用:

Downloader().startDownload("xx.com/file/xx",{ println("下载完毕")})

可以看到,我们只需要传递一个lambda表达式,并在其中编写我们的代码,之后,startDownload方法就会自动回调我们里面写的方法,如下面截图所示;

上面的写法我们可以更加优雅点,可以写成下面的形式:

Downloader().startDownload("xx.com/file/xx"){ println("下载完毕")}

是不是感觉有那味了,没错,如果我们的方法参数只有一个参数,且此参数为接口类型,那么我们就可以像setOnClickListener那样的书写了

PS:基于上面的实践,我们编写方法,如果需要传递接口类型,可以考虑把接口参数定义为最后一个参数,这样,调用的时候可以更为的优雅

进阶,回传数据

如果你需要接口回调某些参数供你调用的时候使用,你可以定义接口参数为((text:String)->String),下面给出一个例子

class Downloader{

    fun startDownload(url:String,downloadFinishListener:((url:String)->Unit)){
        println("下载文件地址为$url")
        println("下载中...")
		//回调接口,并回传当前的url
		downloadListener.invoke(url)
    }
}

上述的方法中,我将url的数据回传给了接口使用,你可以根据实际需要自由地定义需要返回的数据,多参数还是和之前一样,只需要加个逗号隔开即可

接口参数可为空的情况

如果接口参数为全局变量,我们可以将其定义为空类型,这样,如果为空的时候,则不回进行接口的回调

class Downloader{

    fun startDownload(url:String,downloadFinishListener: ((url:String)->Unit)? =null){
        println("下载文件地址为$url")
        println("下载中...")
		//回调接口,并回传当前的url
		//如果为null,则不会回调,无需判空
		downloadListener?.invoke(url)
    }
}
相关标签