kotlin

kotlin 扩展方法

2020-01-02  本文已影响0人  折剑游侠

扩展方法可以在不修改或继承原类的情况下给原类添加方法,当然扩展方法并不是真正的添加进了原类。

下面通过一个例子看看kotlin是怎么处理的。

将double format成常见的金钱格式:10000->10,000

fun Double.format2Money(): String {
    val pattern = "###,###.##"
    val df = DecimalFormat(pattern)
    return df.format(this)
}

调用

val money = 10000.format2Money()

反编译成java:tools->Kotlin->Show Kotlin Bytecode->Decompile

public final class MoneyUtilsKt {
   @NotNull
   public static final String format2Money(double $receiver) {
      String pattern = "###,###.##";
      DecimalFormat df = new DecimalFormat(pattern);
      String var10000 = df.format($receiver);
      Intrinsics.checkExpressionValueIsNotNull(var10000, "df.format(this)");
      return var10000;
   }
}

kotlin生成了静态方法,将调用者当做参数$receiver传入该方法。和自己写的uitls也没啥分别。虽然是糖,但是用起来舒服。而且阅读性较强,还可以配合kotlin封装好的高阶函数使用。

给Activity添加dialog扩展函数

inline fun Activity.customDialog(block: AlertDialog.Builder.() -> Unit): AlertDialog =
    AlertDialog.Builder(this)
        .apply {
            block()
        }
        .show()

inline fun Fragment.customDialog(block: AlertDialog.Builder.() -> Unit): AlertDialog =
    AlertDialog.Builder(activity)
        .apply {
            block()
        }
        .show()

inline fun AlertDialog.Builder.positiveButton(
    text: String = "确定",
    crossinline block: (dialog: DialogInterface) -> Unit
) {
    this.setPositiveButton(text) { dialog, _ ->
        block(dialog)
    }
}

inline fun AlertDialog.Builder.negativeButton(
    text: String = "取消",
    crossinline block: (dialog: DialogInterface) -> Unit
) {
    this.setNegativeButton(text) { dialog, _ ->
        block(dialog)
    }
}

inline fun AlertDialog.Builder.neutralButton(
    text: String = "知道了",
    crossinline block: (dialog: DialogInterface) -> Unit
) {
    this.setNeutralButton(text) { dialog, _ ->
        block(dialog)
    }
}

Activity中调用

customDialog {
    setTitle("title")
    setMessage("message")
    positiveButton {
        it.dismiss()
    }
    negativeButton {
        it.dismiss()
    }
    neutralButton{
        it.dismiss()
    }
}

之前有分析过run函数,回看一下

public inline fun <T, R> T.run(block: T.() -> R): R {
    return block()
}

kotlin封装的几个高阶函数是T类型的扩展方法,任何对象都可调用。

实战一下

inline fun <T> T.customDialog(block: AlertDialog.Builder.() -> Unit): AlertDialog =
    AlertDialog.Builder(ActivityUtils.getTopActivity())
        .apply {
            block()
        }
        .show()

这里只是示范,不建议这样写。如果不需要调用者T,去掉泛型就是个普通的静态方法。

添加通用性较强的方法

inline fun <reified T> T.ktxLog(msg:String) = Log.d(T::class.java.name, msg)

简单说下关键字reified。inline方法中reified修饰泛型后,通过T::class.java拿到class对象,也就是具体化泛型。

上一篇 下一篇

猜你喜欢

热点阅读