当前位置: 首页 > news >正文

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 模板考虑进去,但是足够应付大部分。并且如果所有的都考虑进去和一个个单独写没区别了,所以每个人根据自己实际情况来吧。
项目源码 github.com/GuoZhaoHui6… 如果帮到你,Star 支持下下 thx

相关文章:

  • innerWidth outerWidth
  • 共享单车运营方不能“只管生不管养”
  • 多项底层技术发力,我国物联网大规模商用迎来窗口期
  • 概念大热的区块链,有这些值得关注的特性
  • Storm笔记整理(四):Storm核心概念与验证——并行度与流式分组
  • 公费出书流程
  • centos7 yum安装配置redis 并设置密码
  • 美元汇率 题解
  • MySql查询最近一个月,一周,一天
  • IDC:今年VR+AR市场规模将达到139亿美元
  • CentOS7 安装JDK
  • OSINT系列:威胁信息挖掘ThreatMiner
  • 数据结构化与保存
  • Java 异常基础详解
  • 面向对象进阶-----反射 getattr 和hasattr方法
  • Apache Pulsar 2.1 重磅发布
  • HTTP中的ETag在移动客户端的应用
  • JS函数式编程 数组部分风格 ES6版
  • JS专题之继承
  • Redis 中的布隆过滤器
  • spring学习第二天
  • STAR法则
  • Vue2 SSR 的优化之旅
  • Webpack4 学习笔记 - 01:webpack的安装和简单配置
  • 阿里云购买磁盘后挂载
  • 两列自适应布局方案整理
  • 全栈开发——Linux
  • 融云开发漫谈:你是否了解Go语言并发编程的第一要义?
  • 深度学习入门:10门免费线上课程推荐
  • 使用 @font-face
  • 一个完整Java Web项目背后的密码
  • 一起参Ember.js讨论、问答社区。
  • 用Canvas画一棵二叉树
  • 阿里云重庆大学大数据训练营落地分享
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • 第二十章:异步和文件I/O.(二十三)
  • ​香农与信息论三大定律
  • #define,static,const,三种常量的区别
  • #pragma预处理命令
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • #考研#计算机文化知识1(局域网及网络互联)
  • #使用清华镜像源 安装/更新 指定版本tensorflow
  • #数学建模# 线性规划问题的Matlab求解
  • (ros//EnvironmentVariables)ros环境变量
  • (阿里云万网)-域名注册购买实名流程
  • (补)B+树一些思想
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (算法)求1到1亿间的质数或素数
  • (五)网络优化与超参数选择--九五小庞
  • (原創) 物件導向與老子思想 (OO)
  • (转)setTimeout 和 setInterval 的区别