您好,欢迎来到12图资源库!分享精神,快乐你我!我们只是素材的搬运工!!
  • 首 页
  • 当前位置:首页 > 开发 > WEB开发 >
    Kotlin 作风,应该这样写drawable !(2)
    时间:2021-08-18 12:07 来源:网络整理 作者:网络 浏览:收藏 挑错 推荐 打印

                    final Class<? extends Drawable> clazz = mClassLoader.loadClass(className).asSubclass(Drawable.class); 

                    constructor = clazz.getConstructor(); 

                    CONSTRUCTOR_MAP.put(className, constructor); 

                } 

            } 

            return constructor.newInstance(); 

        } catch (NoSuchMethodException e) { 

        ... 

    代码完成

    由于创立shape等需求设置各种属性来构建,比较契合build设计形式,那我们首先封装build形式的shapeBuilder,这样做虽然代码比起直接运用apply{}要多,但是可以让纯java项目用起来很舒适,其他完成请查看源码:

    class ShapeBuilder : DrawableBuilder { 

        private var mRadius = 0f 

        private var mWidth = 0f 

        private var mHeight = 0f 

        ... 

        private var mShape = GradientDrawable.RECTANGLE 

        private var mSolidColor = 0 

     

        /**辨别设置四个角的圆角*/ 

        fun corner(leftTop: Float,rightTop: Float,leftBottom: Float,rightBottom: Float): ShapeBuilder { 

            ....if(dp)dp2px(leftTop) else leftTop 

            return this 

        } 

     

        fun solid(@ColorRes colorId: Int): ShapeBuilder { 

            mSolidColor = ContextCompat.getColor(context, colorId) 

            return this 

        } 

        // 省略其他参数设置办法 详细代码查看源码 

        override fun build(): Drawable { 

            val gradientDrawable = GradientDrawable() 

            gradientDrawable = GradientDrawable() 

            gradientDrawable.setColor(mSolidColor) 

            gradientDrawable.shape = mShape 

            ....其他参数设置 

            return gradientDrawable 

        }     

    把build形式转换为dsl

    实际上一切的build形式都可以轻松转换为dsl写法:

    inline fun shapeDrawable(builder: ShapeBuilder.() -> Unit): Drawable { 

        return ShapeBuilder().also(builder).build() 

    //运用办法  

    val drawable = shapeDrawable{ 

        ... 

    备注:dsl用法参见juejin.cn/post/695318… 中dsl小节

    函数去括号

    经过下面封装曾经完成了dsl的写法,通常setBackground可以经过setter简化,但是我发现由于有些api设计还需求加括号,这样不太kotlin:

    //容易阅读 

    iv1.background = shapeDrawable { 

        shape(ShapeBuilder.Shape.RECTANGLE) 

        solid("#ABE2E3"

    //多了括号看起来不舒适 

    iv2.setImageDrawable(shapeDrawable { 

        solid("#84232323"

    }) 

    怎样去掉括号呢?有2种方式infix函数(中缀表达)和property setter

    infix函数特点和标准:

    Kotlin允许在不运用括号和点号的状况下调用函数

    必须只要一个参数

    必须是成员函数或扩展函数

    不支持可变参数和带默许值参数

    /**为一切ImageView添加扩展infix函数 来去掉括号*/ 

    infix fun ImageView.src(drawable: Drawable?) { 

        this.setImageDrawable(drawable) 

    //运用如下 

    iv2 src shapeDrawable { 

        shape(ShapeBuilder.Shape.OVAL) 

        solid("#E3ABC2"

    当然了代码是用来阅读的。团体以为假设我们少量运用infix函数,阅读困难会大大添加,所以建议函数命名必须可以直击函数功用,而且函数功用复杂且单一。

    property setter方式,主要运用kotlin可以简化setter为 变量 =来去括号:

    /**扩展变量*/ 

    var ImageView.src: Drawable 

        get() = drawable 

        set(value) { 

            this.setImageDrawable(value) 

        } 

    //运用如下    

    iv2.src = shapeDrawable { 

        shape(ShapeBuilder.Shape.OVAL) 

        solid("#E3ABC2"

    }  

    感谢@叮凛凛 指点,欢迎大家讨论一同窗习,共同提高。

    优缺陷

    优点:

    代码直接创立比起xml方式可以提升功用

    dsl方式比起build形式和调用办法设置愈加繁复契合kotlin作风

    经过适宜的代码管理可以复用这些代码,比xml管理方便

    缺陷:

    没有as的预览功用,只要经过上机观测

    api还没有掩盖一切drawable属性(例如shape = ring等)

    后语

    下面把的DrawableDsl基础用法引见完了,欢迎大家运用,欢迎提Issues,记得给个star哦。Github链接:https://github.com/forJrking/DrawableDsl

    (责任编辑:admin)