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

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

<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完成圆角

//自定义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的扩展函数类似。已然这样我们可以通过代码配备更多自定义的特色:

各方向圆角的完成:

//自定义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}"//右下角

虚线描边:

//自定义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}"

骤变色的运用:

//自定义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文件的全部内容,希望能给我们带来协助!