0.前言
刚刚接触这几个作用域函数真的是傻傻分不清楚,完全搞不懂。经过一段时间的使用和学习,发现。为什么官方把它们叫做作用域函数呢?因为它们最大的作用是规范代码,把对象的一些列操作限定在一个代码块中(作用域)。各个对象层次分明,结构清晰。
不同的作用域函数,区别在于以用调用对象的方式和返回值。
1.先看一段
如下代码通过代码初始化textView属性,margin,shape圆角,可以说是用kotlin写的java代码。
即便在代码中添加了注释和空行分隔,可读性也没有那么好。
//代码创建 drawable 添加背景色 圆角
val drawable = GradientDrawable()
drawable.color= ContextCompat.getColorStateList(applicationContext, R.color.purple_700)
drawable.cornerRadius= 16f
//获取 LayoutParams 设置margin
val margin =
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16f,resources.displayMetrics)
.toInt()
val layoutParams = mBinding.tvButton.layoutParamsas ViewGroup.MarginLayoutParams
//为了代码效果 没有调用 setMargins()
layoutParams.marginStart= margin
layoutParams.marginEnd= margin
layoutParams.topMargin = margin
layoutParams.bottomMargin = margin
//初始化 textView属性
mBinding.tvButton.textSize= 18f
mBinding.tvButton.setTextColor(ContextCompat.getColor(applicationContext, R.color.white))
mBinding.tvButton.text= "按钮"
mBinding.tvButton.gravity= Gravity.CENTER
mBinding.tvButton.background= drawable
mBinding.tvButton.layoutParams= layoutParams
2.作用域函数操作
使用作用域函数后,不同对象的代码被限制在各自的代码块中。
代码中为了给layoutParams 设置margin初始化了一个局部变量 margin。 在传统操作中margin变量任意一个变量都可以访问到。
但实际上只有layoutParams 才用到。 而使用kotlin作用域函数后,margin变量就只能由layoutParams访问,体现出了作用域的概念。
//代码创建 drawable 添加背景色 圆角
val drawable = GradientDrawable().apply {
color = ContextCompat.getColorStateList(applicationContext, R.color.purple_700)
cornerRadius = 16f
}
//设置margin
val layoutParams = mBinding.tvButton.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.run {
val margin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16f, resources.displayMetrics).toInt()
marginStart = margin
marginEnd = margin
topMargin = margin
bottomMargin = margin
}
//初始化 textView属性
mBinding.tvButton.let {
it.textSize = 18f
it.setTextColor(ContextCompat.getColor(applicationContext, R.color.white))
it.text = "按钮"
it.gravity = Gravity.CENTER
it.background = drawable
it.layoutParams = layoutParams
}
3.作用域函数的区别
- 从返回值看
- also,apply属于同一类,返回调用对象
- let,run,with属于一类,最后一行不是return语句或一个变量时,不返回。图2说明如何返回值
- 从上下文对象引用方式看
- also,let属于一类,通过it引用对象
- apply,run,with属于一类,可直接调用属性