Kotlin那些让人相见恨晚的小技巧

Kotlin那些让人相见恨晚的小技巧

1.扩展

方法名左边写个类名加个点,就像钻进这个类的源码改了它里面代码一样,左边的类表示哪个类可以调用这个扩展函数。扩展是一种静态行为,对被扩展的类代码本身不会造成任何影响。

fun receiverType.functionName(params){
    body
}
  • receiverType:表示函数的接收者,也就是函数扩展的对象
  • functionName:扩展函数的名称
  • params:扩展函数的参数,可以为NULL

防止快速点击

/**
 * 防止快速点击
 */
fun View.setSingleClick(clickAction: (view: View) -> Unit) {
    
    
    val minTime = 1000L
    var lastTime = 0L
    this.setOnClickListener {
    
    
        val tmpTime = System.currentTimeMillis()
        if (tmpTime - lastTime > minTime) {
    
    
            lastTime = tmpTime
            clickAction.invoke(this)
        }
    }
}

使用:

binding.ivSetting.setSingleClick {
    
    
    // 点击后的跳转
}

优雅判空

以前经常写这种代码:

String name = etName.getText().toString();
if (TextUtils.isEmpty(name)) {
    
    
    ToastTools.showShort("姓名不能为空");
    return;
}

String password = ...
if (TextUtils.isEmpty(password)) {
    
    
    ...
    return;
}
/**
 * EditText优雅判空
 */
fun TextView.getText(message: String): String? {
    
    
    val text = this.text.toString()
    if (TextUtils.isEmpty(text)) {
    
    
        ToastTools.showShort(message)
        return null
    }
    return text
}

使用:

val name = etName.getText("姓名不能为空") ?: return

单位转换

val Float.dp2px
    get() = TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        this,
        Resources.getSystem().displayMetrics
    )

使用:

val padding = 16.0f.dp2px

扩展点击范围

/** * 扩展控件点击范围 * @param leftSize 左侧扩展的大小(像素) * @param topSize 上侧扩展的大小(像素) * @param rightSize 右侧扩展的大小(像素) * @param bottomSize 下侧扩展的大小(像素) */fun View.expandClick(leftSize: Int = 16, topSize: Int = 16, rightSize: Int = 16, bottomSize: Int = 16) {
    
        val viewParent = parent as View    val view = this    viewParent.post {
    
            val delegateArea = Rect()        view.getHitRect(delegateArea)        delegateArea.left -= leftSize        delegateArea.top -= topSize        delegateArea.right += rightSize        delegateArea.bottom += bottomSize        viewParent.touchDelegate = TouchDelegate(delegateArea, view)    }}

权限申请

原生的申请,涉及到申请的地方和onRequestPermissionsResult()方法,一次申请多个权限之后需要到这个方法里循环遍历,还要想办法区分用户是“拒绝一次”还是“始终拒绝”。现在:

/** * 申请权限扩展 */fun FragmentActivity.requestPermissions(    vararg permissions: String,    message: String = "",    callback: ((granted: Boolean, temp: Boolean) -> Unit)? = null) {
    
        if (permissions.isNotEmpty()) {
    
            RxPermissions(this).requestEachCombined(*permissions)            .subscribe(Consumer() {
    
                    if (!TextUtils.isEmpty(message) && !it.granted) {
    
                        ToastTools.showShort(message)                }                callback?.invoke(it.granted, it.shouldShowRequestPermissionRationale)            })    }}

使用:

requestPermissions(Manifest.permission.CAMERA) {
    
     grant, temp ->    if (grant) {
    
            ToastTools.showShort("granted")    } else {
    
            ToastTools.showShort("deny")    }}

启动界面

/** * 简单地启动Activity */inline fun <reified T : Activity> Context.openActivity() {
    
        val startIntent = Intent(this, T::class.java)    startActivity(startIntent)}

使用:

openActivity<MainActivity>()

2.可以直接使用的类

data class

不用写一大堆getter/setter了

data class User(val name: String, val age: Int)

Object class

懒汉式?饿汉式?多线程是否安全?写单例再也不用双层加锁判断、或者静态类实现了,就一句话

object StoreManager {
    
    }

3.其他

可选参数

以前经常这样写很多重载方法:

扫描二维码关注公众号,回复: 13209360 查看本文章
public void doSomething(int a) {
    
    }public void doSomething(String s) {
    
    }public void doSomething(int a, String s) {
    
    }

现在:

fun doSomething(a:Int = 0, s:String = "") {
    
    }

原生字符串

String json = "{\"msg\": \"操作成功\",\"code\": 0,\"data\": {}}";

现在:

val json = """{"msg": "操作成功","code": 0,"data": {}}"""

字符串拼接

String s = "abc" + v + "def";

现在:

val s = "abc${
      
      v}def"

猜你喜欢

转载自blog.csdn.net/ithouse/article/details/120176664