2、kotlin的一些高级应用

一、let,with,run,apply,also函数的使用及区别

函数名使用方法it,this对象返回值是否是扩展函数适用的场景
letobject.let{ it.xxx }it指代当前对象闭包形式返回适用于处理不为null的操作场景
withwith(object){ xxx }this指代当前对象或者省略闭包形式返回适用于调用同一个类的多个方法时,可以省去类名重复,直接调用类的方法即可,经常用于Android中RecyclerView中onBinderViewHolder中,数据model的属性映射到UI上
runobject.run{ xxx }this指代当前对象或者省略闭包形式返回适用于let,with函数任何场景。
applyobject.apply{ xxx }this指代当前对象或者省略返回this1、适用于run函数的任何场景,一般用于初始化一个对象实例的时候,操作对象属性,并最终返回这个对象。 2、动态inflate出一个XML的View的时候需要给View绑定数据也会用到. 3、一般可用于多个扩展函数链式调用 4、数据model多层级包裹判空处理的问题
alsoobject.also{ xxx }it指代当前对象返回it适用于let函数的任何场景,一般可用于多个扩展函数链式调用

二、Kotlin DSL

例子:

val yesterday = 1.days.ago     //1.days.ago  //val yesterday = 1 天 前

str should startWith("kot")

1.定义
  • DSL(domain specific language),即领域专用语言:专门解决某一特定问题的计算机语言,比如大家耳熟能详的 SQL 和正则表达式。
  • 就简单的来讲,一个行业的专家(比如理论算法专家)准备去协助你的工作,但是他不会写代码,这该怎么办呢?
  • 那他总会汉语吧,对,Kotlin DSL就是要设计出类似汉语这种人人都会的工具,让他们用口头话就能进行编程,从而帮助非码农人士来完成开发。
2.实现原理
  • 看了那么多 Kotlin DSL 的风格和使用场景,相较于刻板的、传统的 Java 而言,更加神奇和富有想象力。要理解 Kotlin DSL 这场魔术盛宴,就必须了解其背后用到的魔术道具——扩展函数lambda中缀调用invoke 约定
3.具体实现
  • 就拿 1 days ago来举例吧
  • 首先1是Int类型,肯定没有days()函数,所以要用到拓展函数
fun Int.days(){//具体实现}
  • 结合 Java8 的 Time api,此处将会涉及到两个扩展函数,完整实现如下:

    fun Int.days() = Period.ofDays(this)
    fun Period.ago() = LocalDate.now() - this
    

    若要实现最终的效果,实际上就是将扩展函数修改为扩展属性的方式即可(扩展属性需提供getter或setter,本质上等同于扩展函数):

    //val Int.days:Period
        //get() = Period.ofDays(this)
    
    //val Period.ago:LocalDate
        //get() = LocalDate.now() - this
    
    objectinfix fun Int.(ago:) = LocalDate.now() - Period.ofDays(this)
    
    println(1 天 前)
    

    代码虽少,却天马行空,妙趣横生。

三、JetPack Compose开发安卓应用

1、Jetpack Compose是什么

Jetpack Compose 是用于构建原生 Android 界面的新工具包。它使用更少的代码、强大的工具和直观的 Kotlin API,可以帮助开发者简化并加快 Android 界面开发。

在此之前,我们如何实现一个业务功能呢?我们是在Activity中编写Java/Kotlin的代码,在XML中编写布局代码,这种方式是我们已经使用了很久的方式,而Jetpack Compose完全抛弃了之前的方式,新创造了一种“使用代码”编写页面的方式,而这种方式,有一个好听的名字,叫做声明式UI

2.示例、
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            FirstComposeTheme {
                // A surface container using the 'background' color from the theme
                Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
                    Greeting(name = "Kotlin")
                }
            }
        }
    }
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
            text = "Hello $name!",
            modifier = modifier
    )
}
  • setContent类似setContentView一样为Activity设置布局,这里的Compose01Theme是根据项目根据名称默认生层的主题,我们后期也可以自己设计出更美观的主题。

  • Greeting函数使用了@Composeable注解称之为组合函数,@Composeable注解注释可告知 Compose 编译器,此函数需要转化为页面显示。

  • Surface()为切片控件(我自己这样称呼的doge),它可以使一块区域有明显的四周阴影(可以设置)。

  • Text()即为文本控件。

[外链图片转存中...(img-2tWZPWgS-1700879555883)]

3、进阶演示(模拟多个好友消息)、
@Composable
fun PhotographerCard(modifier: Modifier = Modifier) {
    //列组件,能使包含在里面的控件按列放置(垂直排列)
    Column {
        CompositionLocalProvider(LocalContentAlpha.provides(ContentAlpha.medium)){
            for(i in 1..5){
                //行组件,水平排列
                Row {
                    //循环十次
                    Surface(
                        modifier = Modifier
                            .size(50.dp).clickable {  },

                        shape = CircleShape,
                        color = MaterialTheme.colors.onSurface.copy(alpha = 0.2f),

                        ) {
                        //图片组件
                        Image(
//                            painter = painterResource(id=R.drawable.img),
                            painter = painterResource(id = when(i){
                                1->R.drawable.img
                                2 -> R.drawable.img2
                                3 -> R.drawable.img3
                                4 -> R.drawable.img4
                                5 -> R.drawable.img5
                                else -> R.drawable.img
                            }),
                            contentDescription = null
                        )
                    }
                    Column(
                        modifier=Modifier
                            .padding(start = 8.dp)
                            .align(Alignment.CenterVertically)
                            .clickable(onClick = {})
                            .padding(16.dp)
                    ){
                        Text(text = when(i){
                            1->"不吃香菜"
                            2->"翻斗花园牛爷爷"
                            3->"咖啡猫"
                            4->"暗夜精灵"
                            5->"纯情女高"
                            else ->"无名氏"
                                           },
                            fontWeight = FontWeight.Bold)
                        Text(text = "$i minutes ago", style = MaterialTheme.typography.body2)


                    }

                }
            }

        }

        }

}

  • 由上面示例我们不难看出,采用jetpack compose开发android app时,每一个Ui控件都是由一个Compose函数表示的,相比较与传统的Xml方式,通过对compose函数直接对函数体内部细节进行修饰,我们可以快速的的页面上控件进行修改。
  • 看似这样会有一点凌乱,其实不然,我们所写的每一个控件都封装在一个Compose函数内,并且还可以在Compose函数内调用另一个Compose函数,这样我们可以先构建整体的布局页面,在到每一个导航栏、盒子、切片,以及再往下的文本,图片等等,一层接一层,很有层次感,容易修改,并且低耦合,不想用哪个控件,直接不调用即可。
四、kotlin协程正在制作中、、、、、、
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐