Kotlin扩展函数在项目中的使用

作者: 奔跑吧李博 | 来源:发表于2021-04-20 01:47 被阅读0次

在Java中,我们要对一个类进行扩展方法,可以采用继承该类新增方法。

Anim原有run方法:
class Anim {
    protected String name;

    Anim(String name) {
        this.name = name;
    }

    protected void run() {
        System.out.println("跑");
    }
}
Dog继承Anim类扩展eat方法:
class Dog extends Anim {

    Dog(String name) {
        super(name);
    }

    /**
     * 扩展eat函数
     */
    protected void eat() {
        System.out.println("吃东西");
    }
}

dog就扩展了eat方法:

var dog = Dog("旺财")
        dog.run()
        dog.eat()
在Kotlin中,我们可以使用扩展函数来新增方法

fun 被扩展类名.扩展函数名( 参数 ) {
//实现代码
}

那么,给Anim加一个扩展方法:

fun Anim.eat(food: String) {
    println("吃$food")
}

Dog类继承Anim,继承了扩展函数eat(food: String),dog调用eat,打印“吃饭”

var dog = Dog("旺财")
        dog.eat("饭")

在java中调kotlin扩展函数:Extends为扩展函数文件名,

ExtendsKt.eat(Dog(), "饭");

如果扩展函数和被扩展类中的成员函数有相同的接收类型、名字和参数,那么这种情况下总是取成员函数。

class Dog {
 
    fun showName(){
        print("Dog")
    }
}
 
fun Dog.showName(){
    print("Cat")
}
 
fun main(args: Array<String>) {
    Dog().showName()
}

如果我们调用 Dog 类的 showName(),它将输出“Dog”,而不是“Cat”。

扩展函数原理

对如下这个扩展函数进行反编译:

fun String.first(num: Int): String {
    return this.substring(0, num)
}

翻译成的代码:

   public static final String first(@NotNull String $this$first, int num) {
      Intrinsics.checkNotNullParameter($this$first, "$this$first");
      byte var3 = 0;
      boolean var4 = false;
      String var10000 = $this$first.substring(var3, num);
      Intrinsics.checkNotNullExpressionValue(var10000, "(this as java.lang.Strin…ing(startIndex, endIndex)");
      return var10000;
   }

编译器会生成一个函数,传入当前扩展类对象作为第一个参数,在函数中对该对象进行一些列处理。

在项目中实际使用

在项目中,我们通常使用扩展函数用来代替Java中的Utils类。比如给Activity、TextView、ImageView、File、Context等类加扩展函数,以达到写工具类的同等效果。

屏幕尺寸转化扩展函数:
fun Context.dp2px(dpValue: Float): Int {
    val scale = resources.displayMetrics.density
    return (dpValue * scale + 0.5f).toInt()
}

fun Context.px2dp(pxValue: Float): Int {
    val scale = resources.displayMetrics.density
    return (pxValue / scale + 0.5f).toInt()
}

fun Context.sp2px(spValue: Float): Int {
    val scale = resources.displayMetrics.scaledDensity
    return (spValue * scale + 0.5f).toInt()
}

fun Context.px2sp(pxValue: Float): Int {
    val scale = resources.displayMetrics.scaledDensity
    return (pxValue / scale + 0.5f).toInt()
}
Activity显示隐藏软键盘扩展函数:
/**
 * 显示软键盘
 */
fun Activity.showKeyboard() {
    var imm: InputMethodManager = this.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
            ?: return
    var view = this.currentFocus
    if (view == null) {
        view = View(this)
        view!!.isFocusable = true
        view!!.isFocusableInTouchMode = true
        view!!.requestFocus()
    }
    imm.showSoftInput(view, InputMethodManager.SHOW_FORCED)
}

/**
 * 隐藏软键盘
 */
fun Activity.hideKeyboard() {
    var imm: InputMethodManager = this.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
            ?: return
    var view = this.currentFocus
    if (view == null) {
        view = View(this)
    }
    imm.hideSoftInputFromWindow(view.windowToken, 0)
}
文件操作扩展函数:
/**
 * 存储bitmap到本地
 * @param bitmap
 * @param file
 * @return
 */
fun Bitmap.bitmapToFile(file: File): Boolean {
    try {
        if (!file.exists()) {
            if (file.parentFile.exists()) file.createNewFile()
        }
        val out = FileOutputStream(file)
        compress(Bitmap.CompressFormat.PNG, 100, out)
        out.flush()
        out.close()
        return true
    } catch (e: FileNotFoundException) {
        e.printStackTrace()
    } catch (e: IOException) {
        e.printStackTrace()
    }
    return false
}

/**
 * 创建文件夹
 *
 * @param path
 * @return
 */
fun String.mkDirs(): File {
    val file = File(this)
    if (!file.exists()) {
        file.mkdirs()
    }
    return file
}

相关文章

网友评论

    本文标题:Kotlin扩展函数在项目中的使用

    本文链接:https://www.haomeiwen.com/subject/qtcwlltx.html