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