IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> drawable用Kotlin应该这样写,已拿offer -> 正文阅读

[移动开发]drawable用Kotlin应该这样写,已拿offer

// infix用法用于去掉括号更加简洁,详细后面说明
image src shapeDrawable {
//指定shape样式
shape(ShapeBuilder.Shape.RECTANGLE)
//圆角,支持4个角单独设置
corner(20f)
//solid 颜色
solid("#ABE2E3")
//stroke 颜色,边框dp,虚线设置
stroke(R.color.white, 2f, 5f, 8f)
}
//按钮点击样式
btn.background = selectorDrawable {
//默认样式
normal = shapeDrawable {
corner(20f)
gradient(90, R.color.F97794, R.color.C623AA2)
}
//点击效果
pressed = shapeDrawable {
corner(20f)
solid("#84232323")
}
}


实现思路
----

### xml如何转换成drawable

xml变成drawable,通过`android.graphics.drawable.DrawableInflater`这个类来IO解析标签创建,然后通过解析标签再设置属性:

//标签创建
private Drawable inflateFromTag(@NonNull String name) {
switch (name) {
case “selector”:
return new StateListDrawable();
case “level-list”:
return new LevelListDrawable();
case “layer-list”:
return new LayerDrawable();

case “color”:
return new ColorDrawable();
case “shape”:
return new GradientDrawable();
case “vector”:
return new VectorDrawable();

}
}
//反射创建
private Drawable inflateFromClass(@NonNull String className) {
try {
Constructor<? extends Drawable> constructor;
synchronized (CONSTRUCTOR_MAP) {
constructor = CONSTRUCTOR_MAP.get(className);
if (constructor == null) {
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`

1.  `infix函数`特点和规范:

*   Kotlin允许在不使用`括号`和点号的情况下调用函数
*   必须只有一个参数
*   必须是成员函数或扩展函数
*   不支持可变参数和带默认值参数

# **总结**

最后对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,**从来都是我们去适应环境,而不是环境来适应我们!**

这里附上上述的技术体系图相关的几十套**腾讯、头条、阿里、美团等公司20年的面试题**,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含**知识脉络 + 诸多细节**,由于篇幅有限,这里以图片的形式给大家展示一部分。

**相信它会给大家带来很多收获:**
![](https://img-blog.csdnimg.cn/img_convert/bf35b9ea6baec659732d0617f84cbfa7.png)

![](https://img-blog.csdnimg.cn/img_convert/ddfa88f9fe9202e0daea76ce9be2af80.png)

> 本文在**[CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》](https://codechina.csdn.net/m0_60958482/android_p7)**中已收录,里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中...


> 当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。

含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中...


> 当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-09-01 12:02:26  更:2021-09-01 12:04:19 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/23 17:28:04-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码