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文件的全部内容,希望能给大家带来帮助!

相关推荐
bianshaopeng1 小时前
android 原生加载pdf
android·pdf
hhzz1 小时前
Linux Shell编程快速入门以及案例(Linux一键批量启动、停止、重启Jar包Shell脚本)
android·linux·jar
火红的小辣椒2 小时前
XSS基础
android·web安全
勿问东西4 小时前
【Android】设备操作
android
五味香4 小时前
C++学习,信号处理
android·c语言·开发语言·c++·学习·算法·信号处理
图王大胜6 小时前
Android Framework AMS(01)AMS启动及相关初始化1-4
android·framework·ams·systemserver
工程师老罗8 小时前
Android Button “No speakable text present” 问题解决
android
小雨cc5566ru9 小时前
hbuilderx+uniapp+Android健身房管理系统 微信小程序z488g
android·微信小程序·uni-app
小雨cc5566ru10 小时前
微信小程序hbuilderx+uniapp+Android 新农村综合风貌旅游展示平台
android·微信小程序·uni-app
小雨cc5566ru10 小时前
小程序 uniapp+Android+hbuilderx体育场地预约管理系统的设计与实现
android·小程序·uni-app