Kotlin代码进阶(二)

Kotlin函数参数默认值

合并前:

fun toast(string: String) {
    toast(string, Toast.LENGTH_SHORT)
}

fun toast(string: String, duration: Int) {
    Toast.makeText(BaseApplication.currentApplication, string, duration).show()
}

合并后:

@JvmOverloads
fun toast(string: String, duration: Int = Toast.LENGTH_SHORT) {
    Toast.makeText(BaseApplication.currentApplication, string, duration).show()
}

在Kotlin中调用,传一个参数或者两个参数,都可以调用

但是,如果在java代码中只能调用2个参数的方法,调用一个参数的方法报错,所以要加一个注解 @JvmOverloads

Kotlin扩展函数

原函数:

fun dp2px(dp: Float): Float {
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics)
}

改为扩展函数:

//扩展函数,相当于在不改变源码的情况下,给Float添加一个新函数dp2px
//调用:6f.dp2px()
fun Float.dp2px(): Float {
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this, displayMetrics)
}

内联函数:inline

fun main() {
    //编译的时候,就是相当于把代码复制过来,可以通过代码转换看出来

    //Log.e("zhoujian","Android开发")
    //Log.e("zhoujian","Kotlin学习")

    logMessage()
}

//内联函数 inline
//作用:减少一层调用栈
//劣势:打包代码量变多
//内联函数 inline对于传入类型是函数参数就有意义的
inline fun logMessage() {
    Log.e("zhoujian", "Android开发")
    Log.e("zhoujian", "Kotlin学习")

}

Kotlin中函数参数类型

fun onClick(view: View) {
    println("View点击了")
}


class View {
    //(view:View)-> Unit 传入的就是一个函数类型
    //函数类型是由函数接受参数、 -> 、函数返回类型三部分构成
    fun setOnClickListener(listener: (view: View) -> Unit) {

    }
}
fun main() {
    
    var view: View = View()
    //传入一个函数 两个冒号+函数名  就把函数传进来了
    //view.setOnClickListener(::onClick)
    //另外一种传递方式:Lambda表达式方式传递函数参数
    view.setOnClickListener {
        println("View点击了")
    }

}

在java中调用 函数参数

       //在java中调用函数参数
        View view = new View();
        view.setOnClickListener(new Function1<View, Unit>() {
            @Override
            public Unit invoke(View view) {
                return null;
            }
        });

对于不是内联函数的函数,传入函数类型参数,会产生额外对象,浪费内存

如果使用内联函数,就不会产生额外的对象

Kotlin中的 by lazy

    override val presenter by lazy {
        // presenter第一次使用时创建,而且对象只会被创建一次
        LessonPresenter(this)
    }

Kotlin中的标准函数(或者叫作用域函数)

run  with  apply  also  let 

主要区别是:返回参数不一样;作用域代码块中指代的调用者参数不一样(this 、 it)

标准函数的作用:可以将逻辑连贯代码放在一个作用域里面,让代码可读性更好

初始化Paint,并设置初始值,这是一个逻辑连贯的代码

改造前:


    private val paint: Paint = Paint()
    //:super(context,attrs) 调用父类构造函数
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        setTextSize(TypedValue.COMPLEX_UNIT_SP, 18f)
        gravity = Gravity.CENTER
        setBackgroundColor(getContext().getColor(R.color.colorPrimary))
        setTextColor(Color.WHITE)

        paint.isAntiAlias = true
        paint.style = Paint.Style.STROKE
        paint.color = getContext().getColor(R.color.colorAccent)
        paint.strokeWidth = 6f.dp2px()
        updateCode()
    }

改造后:


    private val paint: Paint = Paint().apply {
        this.isAntiAlias = true
        this.style = Paint.Style.STROKE
        this.color = getContext().getColor(R.color.colorAccent)
        this.strokeWidth = 6f.dp2px()
    }
    //:super(context,attrs) 调用父类构造函数
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        setTextSize(TypedValue.COMPLEX_UNIT_SP, 18f)
        gravity = Gravity.CENTER
        setBackgroundColor(getContext().getColor(R.color.colorPrimary))
        setTextColor(Color.WHITE)

        updateCode()
    }

或者用 let

    private val paint: Paint = Paint().let {
        it.isAntiAlias = true
        it.style = Paint.Style.STROKE
        it.color = getContext().getColor(R.color.colorAccent)
        it.strokeWidth = 6f.dp2px()
        return@let it
    }

改造前:

            val state:Lesson.State? = lesson.state
            if (state != null) {
                setText(R.id.tv_state, state.stateName())
                var colorRes = when (state) {
                    Lesson.State.PLAYBACK -> R.color.playback
                    Lesson.State.LIVE -> R.color.live
                    Lesson.State.WAIT -> R.color.wait
                }
                val backgroundColor = itemView.context.getColor(colorRes)
                getView<View>(R.id.tv_state).setBackgroundColor(backgroundColor)
            }

改造后:

           lesson.state?.let {
                setText(R.id.tv_state, it.stateName())
                var colorRes = when (it) {
                    Lesson.State.PLAYBACK -> R.color.playback
                    Lesson.State.LIVE -> R.color.live
                    Lesson.State.WAIT -> R.color.wait
                }
                val backgroundColor = itemView.context.getColor(colorRes)
                getView<View>(R.id.tv_state).setBackgroundColor(backgroundColor)
            }

最后一个例子:

改造前:

        refreshLayout = findViewById(R.id.swipe_refresh_layout)
        refreshLayout!!.setOnRefreshListener { presenter.fetchData() }
        refreshLayout!!.isRefreshing = true

改造后:

        refreshLayout = findViewById(R.id.swipe_refresh_layout)
        refreshLayout.apply {
            setOnRefreshListener { presenter.fetchData() }
            isRefreshing = true
        }
发布了272 篇原创文章 · 获赞 68 · 访问量 40万+

猜你喜欢

转载自blog.csdn.net/u014005316/article/details/104358397