Android:解放自己的双手,无需手动创建shape文件

大家好,我是似曾相识2022。不喜欢唱跳篮球,但对杰伦的Rap却情有独钟。

现在的移动应用中为了美化界面,会给各类视图增加一些圆角、描边、渐变等等效果。当然系统也提供了对应的功能,那就是创建shape 标签的XML 文件,例如下图就是创建一个圆角为10dp,填充是白色的shape文件。再把这个文件设置给目标视图作为背景,就达到了我们想要的圆角效果。

ini 复制代码
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="8dp" />
    <solid android:color="#FFFFFF" />
</shape>

//圆角效果
android:background="@drawable/shape_white_r10"

但不是所有的圆角和颜色都一样,甚至还有四个角单独一个有圆角的情况,当然还有描边、虚线描边、渐变填充色等等各类情况。随着页面效果的多样和复杂性,我们添加的shape文件也是成倍增加。

这时候不少的技术大佬出现了,大佬们各显神通打造了许多自定义View。这样我们就可以使用三方库通过在目标视图外嵌套一层视图来达到原本的圆角等效果。不得不说,这确实能够大大减少我们手动创建各类shape的情况,使用起来也是得心应手,方便了不少。

问题:

简单的布局,嵌套层级较少的页面使用起来还好。但往往随着页面的复杂程度越高,嵌套层级也越来多,这个时候再使用三方库外层嵌套视图会越来越臃肿和复杂。那么有没有一种方式可以直接在XML中当前视图中增减圆角等效果呢?

还真有,使用DataBinding可以办到!

这里就不单独介绍DataBinding 的基础配置,网上一搜到处都是。咱们直接进入正题,使用**@BindingAdapter** 注解,这是用来扩展布局XML属性行为的注解。

使用DataBinding实现圆角

ini 复制代码
//自定义shape_radius、shape_solidColor字段  即圆角和填充颜色
@BindingAdapter(value = ["shape_radius","shape_solidColor"])
fun View.setViewBackground(radius: Int = 0,solidColor: Int = Color.TRANSPARENT){
    val drawable = GradientDrawable()
    drawable.cornerRadius = context.dp2px(radius.toFloat()).toFloat()
    drawable.setColor(solidColor)
    background = drawable
}

//xml文件中
shape_radius="@{10}"
shape_solidColor="@{@color/white}"

其实就是对当前视图的一个扩展,有点和kotlin的扩展函数类似。既然这样我们可以通过代码配置更多自定义的属性:

各方向圆角的实现:

less 复制代码
//自定义shape_radius、shape_solidColor字段  即圆角和填充颜色
@BindingAdapter(value = ["
"shape_solidColor",//填充颜色
"shape_tl_radius",//上左圆角
"shape_tr_radius",//上右圆角
"shape_bl_radius",//下左圆角
"shape_br_radius"//下右圆角
])
fun View.setViewBackground(radius: Int = 0,solidColor: Int = Color.TRANSPARENT){
    val drawable = GradientDrawable()
    drawable.setColor(solidColor)
    drawable.cornerRadii = floatArrayOf(
            context.dp2px(shape_tl_radius.toFloat()).toFloat(),
            context.dp2px(shape_tl_radius.toFloat()).toFloat(),
            context.dp2px(shape_tr_radius.toFloat()).toFloat(),
            context.dp2px(shape_tr_radius.toFloat()).toFloat(),
            context.dp2px(shape_br_radius.toFloat()).toFloat(),
            context.dp2px(shape_br_radius.toFloat()).toFloat(),
            context.dp2px(shape_bl_radius.toFloat()).toFloat(),
            context.dp2px(shape_bl_radius.toFloat()).toFloat(),
        )
    background = drawable
}

//xml文件中
shape_radius="@{10}"
shape_tl_radius="@{@color/white}"//左上角
shape_tr_radius="@{@color/white}"//右上角
shape_bl_radius="@{@color/white}"//左下角
shape_br_radius="@{@color/white}"//右下角

虚线描边:

ini 复制代码
//自定义shape_radius、shape_solidColor字段  即圆角和填充颜色
@BindingAdapter(value = [
"shape_radius",
"shape_solidColor",
"shape_strokeWitdh",//描边宽度
"shape_dashWith",//描边虚线单个宽度
"shape_dashGap",//描边间隔宽度
])
fun View.setViewBackground(
radius: Int = 0,
solidColor: Int = Color.TRANSPARENT,
strokeWidth: Int = 0,
shape_dashWith: Int = 0,
shape_dashGap: Int = 0
){
    val drawable = GradientDrawable()
    drawable.setStroke(
        context.dp2px(strokeWidth.toFloat()),
        strokeColor,
        shape_dashWith.toFloat(),
        shape_dashGap.toFloat()
    )
    drawable.setColor(solidColor)
    background = drawable
}

//xml文件中
shape_radius="@{10}"
shape_solidColor="@{@color/white}"
strokeWidth="@{1}"
shape_dashWith="@{2}"
shape_dashGap="@{3}"

渐变色的使用:

ini 复制代码
//自定义shape_radius、shape_solidColor字段  即圆角和填充颜色
@BindingAdapter(value = [
"shape_startColor",//渐变开始颜色
"shape_centerColor",//渐变中间颜色
"shape_endColor",//渐变结束颜色
"shape_gradualOrientation",//渐变角度
])
fun View.setViewBackground(
shape_startColor: Int = Color.TRANSPARENT,
shape_centerColor: Int = Color.TRANSPARENT,
shape_endColor: Int = Color.TRANSPARENT,
shape_gradualOrientation: Int = 1,//TOP_BOTTOM = 1 ,TR_BL = 2,RIGHT_LEFT = 3,BR_TL = 4,BOTTOM_TOP = 5,BL_TR = 6,LEFT_RIGHT = 7,TL_BR = 8
){
val drawable = GradientDrawable()
when (shape_gradualOrientation) {
    1 -> drawable.orientation = GradientDrawable.Orientation.TOP_BOTTOM
    2 -> drawable.orientation = GradientDrawable.Orientation.TR_BL
    3 -> drawable.orientation = GradientDrawable.Orientation.RIGHT_LEFT
    4 -> drawable.orientation = GradientDrawable.Orientation.BR_TL
    5 -> drawable.orientation = GradientDrawable.Orientation.BOTTOM_TOP
    6 -> drawable.orientation = GradientDrawable.Orientation.BL_TR
    7 -> drawable.orientation = GradientDrawable.Orientation.LEFT_RIGHT
    8 -> drawable.orientation = GradientDrawable.Orientation.TL_BR
}
drawable.gradientType = GradientDrawable.LINEAR_GRADIENT//线性
drawable.shape = GradientDrawable.RECTANGLE//矩形方正
drawable.colors = if (shape_centerColor != Color.TRANSPARENT) {//有中间色
    intArrayOf(
        shape_startColor,
        shape_centerColor,
        shape_endColor
    )
} else {
    intArrayOf(shape_startColor, shape_endColor)
}//渐变色
background = drawable
}

//xml文件中
shape_startColor="@{@color/cl_F1E6A0}"
shape_centerColor="@{@color/cl_F8F8F8}"
shape_endColor=@{@color/cl_3CB9FF}

不止设置shape 功能,只要可以通过代码设置的功能一样可以在BindingAdapter注解中自定义,使用起来是不是更加方便了。

总结:

  • 注解BindingAdapter中value数组的自定义属性一样要和方法内的参数一一对应,否则会报错。
  • 布局中使用该自定义属性时需要将布局文件最外层修改为layout标签
  • XML中使用自定义属性时一定要添加@{}

好了,以上便是解放自己的双手,无需手动创建shape文件的全部内容,希望能给大家带来帮助!

相关推荐
拭心11 小时前
Google 提供的 Android 端上大模型组件:MediaPipe LLM 介绍
android
带电的小王14 小时前
WhisperKit: Android 端测试 Whisper -- Android手机(Qualcomm GPU)部署音频大模型
android·智能手机·whisper·qualcomm
梦想平凡14 小时前
PHP 微信棋牌开发全解析:高级教程
android·数据库·oracle
元争栈道14 小时前
webview和H5来实现的android短视频(短剧)音视频播放依赖控件
android·音视频
阿甘知识库15 小时前
宝塔面板跨服务器数据同步教程:双机备份零停机
android·运维·服务器·备份·同步·宝塔面板·建站
元争栈道16 小时前
webview+H5来实现的android短视频(短剧)音视频播放依赖控件资源
android·音视频
MuYe16 小时前
Android Hook - 动态加载so库
android
居居飒17 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
Henry_He20 小时前
桌面列表小部件不能点击的问题分析
android
工程师老罗20 小时前
Android笔试面试题AI答之Android基础(1)
android