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

相关推荐
Dnelic-2 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记
Eastsea.Chen4 小时前
MTK Android12 user版本MtkLogger
android·framework
长亭外的少年11 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
JIAY_WX11 小时前
kotlin
开发语言·kotlin
建群新人小猿14 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神15 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛15 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee
Y多了个想法16 小时前
RK3568 android11 适配敦泰触摸屏 FocalTech-ft5526
android·rk3568·触摸屏·tp·敦泰·focaltech·ft5526
NotesChapter17 小时前
Android吸顶效果,并有着ViewPager左右切换
android
_祝你今天愉快18 小时前
分析android :The binary version of its metadata is 1.8.0, expected version is 1.5.
android