Java一行代码控制shape 优雅的解决 Drawable Shape 文件繁多问题

1. 前言

我们知道开发中很多图片可以用 shape 代替,但是当项目过大,功能增多,我们会发现 Drawable 文件夹下面的 .xml 文件越来越多,比如下


这里写图片描述

我们会发现,很多文件都类似,只是颜色 大小等不一样而已,所以每次碰到用到 shape 的地方还得新建 shape .xml 。这样既麻烦并且会造成 drawable .xml文件过多。
所以我希望项目中只建立几个典型常用的 shape 种类,然后通过 java 代码控制颜色或者大小、倒角、渐变方向颜色。

我抽取了几个项目中常用的 shape 样式,分别

  • 纯矩形纯色。【rect+solid】,可以修改颜色
  • 倒角矩形纯色。【rect+solid+corner,可以修改矩形颜色和倒角大小
  • 倒角矩形描边纯色。【rect+solid+corner+stroke】,可以修改矩形颜色,倒圆角大小,描边颜色和大小
  • 矩形渐变。【rect+gradient】矩形线性渐变,可以修改渐变颜色及顺序

做了个demo效果如下


这里写图片描述


2.代码

拿上面demo举例,将上面四个经典常用的 shape 建立出来,都比较简单,只贴 bg_rect_corner_stroke

这里写图片描述

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    >
    <solid android:color="@android:color/holo_blue_dark" />
    <corners android:radius="6dp" />
    <stroke
        android:color="@android:color/holo_orange_dark"
        android:width="1.5dp" />
</shape>

这里写图片描述


中间四个 textview ,特别要注意将 .xml 设置到 background 属性中

 <TextView
        android:layout_marginTop="20dp"
        android:layout_centerHorizontal="true"
        android:gravity="center"
        android:id="@+id/tv1"
        android:background="@drawable/bg_rect"
        android:textSize="20sp"
        android:text="纯矩形纯色"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

下方四个控件也是 textview ,为了方便,注意这里我为每个 textview 设置的 background 和 text,这就是demo中每次点击修改颜色和大小的来源。比如 第一个 颜色绿色 text是4,点击后上方的 shape solid 颜色改变为绿色,倒角或其他大小改变为 4dp

<LinearLayout
        android:layout_alignParentBottom="true"
        android:layout_width="match_parent"
        android:layout_height="30dp">
        <TextView
            android:gravity="center"
            android:text="4"
            android:id="@+id/v1"
            android:background="@color/green"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
        <TextView
            android:gravity="center"
            android:text="6"
            android:id="@+id/v2"
            android:background="@color/brown"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
        <TextView
            android:gravity="center"
            android:text="8"
            android:id="@+id/v3"
            android:background="@color/colorAccent"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
        <TextView
            android:gravity="center"
            android:text="10"
            android:id="@+id/v4"
            android:background="@color/liteBlue"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
    </LinearLayout>


好的!到这里准备工作已经做完,核心代码如下,

   /**
     * 设置 shape 的颜色
     * @param view
     * @param solidColor
     */
    public static void setShapeColor(View view,int solidColor){
        if(view == null){
            return;
        }
        GradientDrawable gradientDrawable = (GradientDrawable) view.getBackground();
        gradientDrawable.setColor(solidColor);
    }

前面我们将 shape.xml 设置到控件的 background ,在 java 代码中可以通过 GradientDrawable gradientDrawable = (GradientDrawable) view.getBackground(); 获取到 gradientDrawable ,它就是管理 shape 中属性的对象,截取其中部分方法


这里写图片描述
这里写图片描述

对于 setShapeColor 中的两个参数很好理解,view指设置background的控件。在java代码中

    EasyShapeUtils.setShapeColor(tv1,color);

这里写图片描述

后面两种同理,直接贴代码

    /**
     * 设置shape倒角和颜色
     * @param view
     * @param solidColor
     * @param corner
     */
    public static void setShapeCorner2Color(View view, int solidColor, float corner){
        if(view == null){
            return;
        }
        GradientDrawable gradientDrawable = (GradientDrawable) view.getBackground();
        gradientDrawable.setColor(solidColor);
        gradientDrawable.setCornerRadius(corner);
    }

    /**
     * 设置shape倒角 颜色 和描边颜色和大小
     * @param view
     * @param solidColor
     * @param corner
     */
    public static void setShapeCorner2Color2Stroke(View view, int solidColor, float corner,int strokeColor,int strokeWidth){
        if(view == null){
            return;
        }
        GradientDrawable gradientDrawable = (GradientDrawable) view.getBackground();
        gradientDrawable.setColor(solidColor);
        gradientDrawable.setCornerRadius(corner);
        gradientDrawable.setStroke(strokeWidth, strokeColor);
    }

有点特殊的是最后渐变方法代码的书写。

   /**
     * 设置矩形渐变,同时shape渐变类型只能是线性从上倒下,颜色数组中的顺序即是渐变顺序
     * @param view
     * @param colors
     */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public static void setShapeGradient(View view, int[] colors){
        if(view == null){
            return;
        }
        if(colors.length > 3){
            return;
        }
        GradientDrawable gradientDrawable = (GradientDrawable) view.getBackground();
        gradientDrawable.setGradientType(GradientDrawable.LINEAR_GRADIENT);
        gradientDrawable.setColors(colors);
    }

这里方法中第二个参数是颜色数组,这里很有讲究
如果 shape.xml 模板中设置三种渐变颜色 如下

   <gradient
        android:angle="270"
        android:startColor="@android:color/holo_orange_dark"
        android:centerColor="@android:color/holo_blue_bright"
        android:endColor="@android:color/holo_green_dark" />

那么这里颜色数组只能传三种颜色,并且不能少不能多,xml中只设置了两种颜色

   <gradient
        android:angle="270"
        android:startColor="@android:color/holo_orange_dark"
        android:endColor="@android:color/holo_green_dark" />

那这里传入的数组颜色同理。

一定要注意上面,不然很容易出错

因为我项目中之用到了 竖型线性渐变,所以方法中设置渐变的类型是线性的,可以自行修改。
在java中使用
EasyShapeUtils.setShapeGradient(tv4,new int[]{getRandomColor(),color,getRandomColor()});

如果需求是横向的线性渐变,设置下 angle 即可


这里写图片描述


3.完结

使用流程:

将源码中的四个 shape.xml 和 EasyShapeUtils 复制到项目中,为控件设置相应的 shape.xml
background。直接在 Java 中使用相应方法即可

这只是一个思路,没有把所有 shape 模板考虑进去,但是足够应付大部分。并且如果所有的都考虑进去和一个个单独写没区别了,所以每个人根据自己实际情况来吧。

项目源码
https://github.com/GuoZhaoHui628/EasyShapeUtil
如果帮到你,Star 支持下下 thx

猜你喜欢

转载自blog.csdn.net/guozhaohui628/article/details/79916967
今日推荐