废话不多说,先上效果图:

该效果其实由三部分组成:

  • 渐变
  • 圆角
  • 文本

渐变

关于渐变,估计大家都不会陌生,以往都是使用gradient进行制作:

shape_gradient.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"><gradientandroid:startColor="#B620E0"android:endColor="#E38746" />
</shape>
    <Viewandroid:layout_width="match_parent"android:layout_height="70dp"android:background="@drawable/shape_gradient" />

但是,这个只能支持双色渐变,超过双色就无能为力了,所以,我们要考虑使用其它方式:

    /*** Create a shader that draws a linear gradient along a line.** @param x0           The x-coordinate for the start of the gradient line* @param y0           The y-coordinate for the start of the gradient line* @param x1           The x-coordinate for the end of the gradient line* @param y1           The y-coordinate for the end of the gradient line* @param colors       The colors to be distributed along the gradient line* @param positions    May be null. The relative positions [0..1] of*                     each corresponding color in the colors array. If this is null,*                     the the colors are distributed evenly along the gradient line.* @param tile         The Shader tiling mode*/public LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int colors[],@Nullable float positions[], @NonNull TileMode tile)
    /*** x0、y0、x1、y1为决定渐变颜色方向的两个坐标点,x0、y0为起始坐标,x1、y1为终点坐标* @param colors       所有渐变颜色的数组,即放多少个颜色进去,就有多少种渐变颜色* @param positions    渐变颜色的比值,默认为均匀分布。* 把总长度理解为1,假如里面的值为[0.3,0.2,0.5],那么,渐变的颜色就会以 0.3 : 0:2 :0.5 比例进行排版* @param tile         着色器模式*/
public LinearGradient(float x0, float y0, float x1, float y1, int colors[], float positions[],TileMode tile)

创建自定义View

public class ColorView extends View {public ColorView(Context context) {super(context);}public ColorView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);}public ColorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//获取宽高int width = getWidth();int height = getHeight();//渐变的颜色int colorStart = Color.parseColor("#E38746");int color1 = Color.parseColor("#B620E0");int colorEnd = Color.parseColor("#5995F6");//绘画渐变效果Paint paintColor = new Paint();LinearGradient backGradient = new LinearGradient(0, height, width, 0, new int[]{colorStart, color1, colorEnd}, null, Shader.TileMode.CLAMP);paintColor.setShader(backGradient);canvas.drawRect(0, 0, width, height, paintColor);}
}
    <com.jm.xpproject.ColorViewandroid:layout_width="match_parent"android:layout_height="70dp" />

效果:

圆角

关于圆角,我们需要使用到BitmapShader,使用方式:

        BitmapShader bitmapShaderColor = new BitmapShader(bitmapColor, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);// 初始化画笔Paint paintFillet = new Paint();paintFillet.setAntiAlias(true);paintFillet.setShader(bitmapShaderColor);//绘画到画布中canvas.drawRoundRect(new RectF(0, 0, width, height), radius, radius, paintFillet);

由于这里的BitmapShader是对于Bitmap进行操作的,所以,对于渐变效果,我们不能直接把他绘画到原始画布上,而是生成一个Bitmap,将渐变绘画记录下来:

还是刚刚的自定义View

    @Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//获取View的宽高int width = getWidth();int height = getHeight();//第一步,绘画出一个渐变效果的Bitmap//创建存放渐变效果的bitmapBitmap bitmapColor = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);Canvas canvasColor = new Canvas(bitmapColor);//渐变的颜色int colorStart = Color.parseColor("#E38746");int color1 = Color.parseColor("#B620E0");int colorEnd = Color.parseColor("#5995F6");//绘画渐变效果Paint paintColor = new Paint();LinearGradient backGradient = new LinearGradient(0, height, width, 0, new int[]{colorStart, color1, colorEnd}, null, Shader.TileMode.CLAMP);paintColor.setShader(backGradient);canvasColor.drawRect(0, 0, width, height, paintColor);//第二步,绘画出一个圆角渐变效果//绘画出圆角渐变效果BitmapShader bitmapShaderColor = new BitmapShader(bitmapColor, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);// 初始化画笔Paint paintFillet = new Paint();paintFillet.setAntiAlias(true);paintFillet.setShader(bitmapShaderColor);//绘画到画布中canvas.drawRoundRect(new RectF(0, 0, width, height), 100, 100, paintFillet);}

效果:

至于中间的空白部分,其实我们依葫芦画瓢,再画上一个白色的圆角Bitmap即可:

        //创建存放白底的bitmapBitmap bitmapWhite = Bitmap.createBitmap(width - colorWidth * 2, height - colorWidth * 2, Bitmap.Config.RGB_565);bitmapWhite.eraseColor(Color.parseColor("#FFFFFF"));BitmapShader bitmapShaderWhite = new BitmapShader(bitmapWhite, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);// 初始化画笔Paint paintWhite = new Paint();paintWhite.setAntiAlias(true);paintWhite.setShader(bitmapShaderWhite);// 将白色Bitmap绘制到画布上面canvas.drawRoundRect(new RectF(colorWidth, colorWidth, width - colorWidth, height - colorWidth), radius, radius, paintWhite);

总体代码:

@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//获取View的宽高int width = getWidth();int height = getHeight();//第一步,绘画出一个渐变效果的Bitmap//创建存放渐变效果的bitmapBitmap bitmapColor = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);Canvas canvasColor = new Canvas(bitmapColor);//渐变的颜色int colorStart = Color.parseColor("#E38746");int color1 = Color.parseColor("#B620E0");int colorEnd = Color.parseColor("#5995F6");//绘画渐变效果Paint paintColor = new Paint();LinearGradient backGradient = new LinearGradient(0, height, width, 0, new int[]{colorStart, color1, colorEnd}, null, Shader.TileMode.CLAMP);paintColor.setShader(backGradient);canvasColor.drawRect(0, 0, width, height, paintColor);//第二步,绘画出一个圆角渐变效果//绘画出圆角渐变效果BitmapShader bitmapShaderColor = new BitmapShader(bitmapColor, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);// 初始化画笔Paint paintFillet = new Paint();paintFillet.setAntiAlias(true);paintFillet.setShader(bitmapShaderColor);//绘画到画布中canvas.drawRoundRect(new RectF(0, 0, width, height), 100, 100, paintFillet);//第三步,绘画出一个白色的bitmap覆盖上去//创建存放白底的bitmapBitmap bitmapWhite = Bitmap.createBitmap(width - 5 * 2, height - 5 * 2, Bitmap.Config.RGB_565);bitmapWhite.eraseColor(Color.parseColor("#FFFFFF"));BitmapShader bitmapShaderWhite = new BitmapShader(bitmapWhite, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);// 初始化画笔Paint paintWhite = new Paint();paintWhite.setAntiAlias(true);paintWhite.setShader(bitmapShaderWhite);// 将白色Bitmap绘制到画布上面canvas.drawRoundRect(new RectF(5, 5, width - 5, height - 5), 100, 100, paintWhite);}

效果:

文本

像文本就简单了,使用drawText即可,只要注意在绘画的时候,要对文本进行居中显示,因为 Android 默认绘画文本,是从左下角进行绘画的,就像这样:

        Paint paintText = new Paint();paintText.setAntiAlias(true);paintText.setColor(Color.parseColor("#000000"));paintText.setTextSize(100);canvas.drawText("收藏", width / 2, height / 2, paintText);canvas.drawLine(width / 2, 0, width / 2, height, paintText);canvas.drawLine(0, height / 2, width, height / 2, paintText);

正确做法:

        String text = "收藏";Rect rect = new Rect();Paint paintText = new Paint();paintText.setAntiAlias(true);paintText.setColor(Color.parseColor("#000000"));paintText.setTextSize(100);paintText.getTextBounds(text, 0, text.length(), rect);int widthFont = rect.width();//文本的宽度int heightFont = rect.height();//文本的高度canvas.drawText(text, (width - widthFont) / 2, (height+heightFont) / 2, paintText);

至此,基本功能的制作就完成了

@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//获取View的宽高int width = getWidth();int height = getHeight();//第一步,绘画出一个渐变效果的Bitmap//创建存放渐变效果的bitmapBitmap bitmapColor = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);Canvas canvasColor = new Canvas(bitmapColor);//渐变的颜色int colorStart = Color.parseColor("#E38746");int color1 = Color.parseColor("#B620E0");int colorEnd = Color.parseColor("#5995F6");//绘画渐变效果Paint paintColor = new Paint();LinearGradient backGradient = new LinearGradient(0, height, width, 0, new int[]{colorStart, color1, colorEnd}, null, Shader.TileMode.CLAMP);paintColor.setShader(backGradient);canvasColor.drawRect(0, 0, width, height, paintColor);//第二步,绘画出一个圆角渐变效果//绘画出圆角渐变效果BitmapShader bitmapShaderColor = new BitmapShader(bitmapColor, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);// 初始化画笔Paint paintFillet = new Paint();paintFillet.setAntiAlias(true);paintFillet.setShader(bitmapShaderColor);//绘画到画布中canvas.drawRoundRect(new RectF(0, 0, width, height), 100, 100, paintFillet);//第三步,绘画出一个白色的bitmap覆盖上去//创建存放白底的bitmapBitmap bitmapWhite = Bitmap.createBitmap(width - 5 * 2, height - 5 * 2, Bitmap.Config.RGB_565);bitmapWhite.eraseColor(Color.parseColor("#FFFFFF"));BitmapShader bitmapShaderWhite = new BitmapShader(bitmapWhite, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);// 初始化画笔Paint paintWhite = new Paint();paintWhite.setAntiAlias(true);paintWhite.setShader(bitmapShaderWhite);// 将白色Bitmap绘制到画布上面canvas.drawRoundRect(new RectF(5, 5, width - 5, height - 5), 100, 100, paintWhite);String text = "收藏";Rect rect = new Rect();Paint paintText = new Paint();paintText.setAntiAlias(true);paintText.setColor(Color.parseColor("#000000"));paintText.setTextSize(100);paintText.getTextBounds(text, 0, text.length(), rect);int widthFont = rect.width();//文本的宽度int heightFont = rect.height();//文本的高度canvas.drawText(text, (width - widthFont) / 2, (height+heightFont) / 2, paintText);}

封装

上面虽然已经把全部功能都讲解完了,但是,假如就直接这样放入项目中,是极其不规范的,无法动态设置文本、文本大小、颜色厚度等等

这里,我进行了简易封装,大家可以基于此进行业务修改:

attrs.xml

    <declare-styleable name="GradientColorButton"><attr name="btnText" format="string" /><attr name="btnTextSize" format="dimension" /><attr name="btnTextColor" format="color" /><attr name="colorWidth" format="dimension" /><attr name="colorRadius" format="dimension" /></declare-styleable>
public class GradientColorButton extends View {/*** 文本*/private String text = "";/*** 文本颜色*/private int textColor;/*** 文本大小*/private float textSize;/*** 颜色的宽度*/private float colorWidth;/*** 圆角度数*/private float radius;//渐变的颜色private int colorStart = Color.parseColor("#E38746");private int color1 = Color.parseColor("#B620E0");private int colorEnd = Color.parseColor("#5995F6");//控件的宽高private int width;private int height;/*** 渐变颜色的Bitmap*/private Bitmap bitmapColor;//画笔private Paint paintColor;private Paint paintFillet;private Paint paintWhite;private Paint paintText;//字体的宽高private int widthFont;private int heightFont;public GradientColorButton(Context context) {super(context);}public GradientColorButton(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public GradientColorButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);//获取参数TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.GradientColorButton, defStyleAttr, 0);text = a.getString(R.styleable.GradientColorButton_btnText);textColor = a.getColor(R.styleable.GradientColorButton_btnTextColor, Color.BLACK);textSize = a.getDimension(R.styleable.GradientColorButton_btnTextSize, 16);colorWidth = a.getDimension(R.styleable.GradientColorButton_colorWidth, 5);radius = a.getDimension(R.styleable.GradientColorButton_colorRadius, 100);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);//获取View的宽高width = getWidth();height = getHeight();//制作一个渐变效果的BitmapcreateGradientBitmap();//初始化圆角配置initFilletConfiguration();//初始化白色Bitmap配置initWhiteBitmapConfiguration();//初始化文本配置initTextConfiguration();}/*** 创建渐变颜色的Bitmap*/private void createGradientBitmap() {//创建存放渐变效果的bitmapbitmapColor = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);Canvas canvasColor = new Canvas(bitmapColor);LinearGradient backGradient = new LinearGradient(0, height, width, 0, new int[]{colorStart, color1, colorEnd}, null, Shader.TileMode.CLAMP);//绘画渐变效果paintColor = new Paint();paintColor.setShader(backGradient);canvasColor.drawRect(0, 0, width, height, paintColor);}/*** 初始化圆角配置*/private void initFilletConfiguration() {//绘画出圆角渐变效果BitmapShader bitmapShaderColor = new BitmapShader(bitmapColor, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);// 初始化画笔paintFillet = new Paint();paintFillet.setAntiAlias(true);paintFillet.setShader(bitmapShaderColor);}/*** 初始化白色Bitmap配置*/private void initWhiteBitmapConfiguration() {//创建存放白底的bitmapBitmap bitmapWhite = Bitmap.createBitmap((int) (width - colorWidth * 2), (int) (height - colorWidth * 2), Bitmap.Config.RGB_565);bitmapWhite.eraseColor(Color.parseColor("#FFFFFF"));BitmapShader bitmapShaderWhite = new BitmapShader(bitmapWhite, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);// 初始化画笔paintWhite = new Paint();paintWhite.setAntiAlias(true);paintWhite.setShader(bitmapShaderWhite);}/*** 初始化文本配置*/private void initTextConfiguration() {Rect rect = new Rect();paintText = new Paint();paintText.setAntiAlias(true);paintText.setColor(textColor);paintText.setTextSize(textSize);if (!TextUtils.isEmpty(text)) {paintText.getTextBounds(text, 0, text.length(), rect);widthFont = rect.width();//文本的宽度heightFont = rect.height();//文本的高度}}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//将圆角渐变bitmap绘画到画布中canvas.drawRoundRect(new RectF(0, 0, width, height), radius, radius, paintFillet);// 将白色Bitmap绘制到画布上面canvas.drawRoundRect(new RectF(colorWidth, colorWidth, width - colorWidth, height - colorWidth), radius, radius, paintWhite);if (!TextUtils.isEmpty(text)) {canvas.drawText(text, (width - widthFont) / 2, (height + heightFont) / 2, paintText);}}
}
    <com.jm.xpproject.GradientColorButtonandroid:layout_width="120dp"android:layout_height="70dp"android:layout_margin="10dp"app:btnText="收藏"app:btnTextColor="#123456"app:btnTextSize="18sp"app:colorRadius="50dp"app:colorWidth="5dp" />

什么?你连个三色渐变圆角按钮都需要UI切图?相关推荐

  1. 程序员PS技能(三):程序员使用PSD源文件切图

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/106476578 长期持续带来更多技术分享,定制咨询QQ ...

  2. Android gradient 三色渐变背景 Shap

    实现三渐色 在drawable文件夹里新建一个selector文件 <selector xmlns:android="http://schemas.android.com/apk/re ...

  3. Android 实现三色渐变背景

    在drawable文件夹中新建一个selector文件 <?xml version="1.0" encoding="utf-8"?> <sha ...

  4. Qt编写自定义控件:彩色渐变圆角按钮之二

    代码: #ifndef COLORGRADIENTROUNDEDBUTTON_H #define COLORGRADIENTROUNDEDBUTTON_H#include <QAbstractB ...

  5. 菜鸡shader:L3三色环境光材质、阴影及光衰

    三色环境光材质 先放上最终效果 这里将环境光分为上中下三层,顶层是红色的,中间那层是绿色的,下层则是蓝色的.环境光遮蔽效果则是直接采样事先准备好的AO贴图. 首先是上层环境光: 这里我们只需要法线向量 ...

  6. Android渐变色圆角按钮的实现

    最终效果如: 没有使用背景图片,因为Android手机屏幕分辨率碎片化太严重,如果用图片的话需要ps n张图片.所以,使用shape实现的渐变圆角按钮. 1.在drawable文件夹下新建round. ...

  7. Arduino Uno 全彩呼吸灯 三色LED灯渐变实例

    共阳三色雾状LED灯 可以控制三种颜色 ,分别是红,绿,蓝, 通过控制其亮度,可以混合出各种颜色,非常漂亮哦 注意 共阳指接的是正极 共阴指接的是负极 实验效果 引脚 请查看产品大图,最长的引脚为共阳 ...

  8. RVB2601开发板试用2——PWM的使用,既三色小灯驱动

    本文作者:我爱下载 1.概述 RVB2601评估板包含RGB三基色LED一个,为了学习PWM信号的驱动,我们可以通过驱动三基色LED来完成. 2.硬件接口描述 通过如上两个原理图对照可知. 序号 LE ...

  9. html圆角矩形的渐变色,canvas圆角矩形 PS制作渐变圆角矩形: 方法一:

    用canvas画只有一个角是圆角的矩形,能画出来么? CSS布局HTML小编今天和大家分享各位大侠指点, 找到方法了float[] radii={12f,12f,0f,0f,0f,0f,0f,0f}; ...

最新文章

  1. 基于深度学习的图像边缘和轮廓提取
  2. mysql 多维度分表_亿级订单数据分库分表设计方案(满足多维度查询:订单号、用户、商家、渠道)...
  3. java 得到checkbox_【JavaWeb】获得选中的checkbox的value
  4. STM32F4_USART配置及细节描述
  5. Linux计算内存,正确计算linux系统内存使用率
  6. java判断两个矩形是否相交_判断矩形相交以及求出相交的区域
  7. python中filter、map、reduce的区别
  8. 使用java做用一张厚度为0.01米的纸折叠多少次,就可以保证厚度不低于珠穆朗玛峰的高度?
  9. hive之full outer join(全连接)使用方法
  10. OpenCV学习——基本操作之绘制几何图形
  11. 基于51单片机实现计算器功能
  12. (个人记录向)75寸电视选购
  13. URLencode转换
  14. clips系列二-clips调用外部函数
  15. linux怎样安装xz工具,如何安装XZ Utils 解压缩工具以及利用 xz工具来解压缩.xz文件...
  16. 梯度下降法、Epoch、Batchsize、Iterations
  17. 新员工入职详细培训计划
  18. React Native 之组件的定义
  19. 银行自动分账应该怎么对接?
  20. 部署了HTTPS以后重新验证证书如何取消301跳转

热门文章

  1. easyexcel使用问题:使用时导出的excel文件损坏,打开不了,后台没异常错误
  2. Inspector检视视图
  3. 针对儿子买的将近一万的笔记本电脑
  4. excel项目计划_使用Excel计划您的聚会座位
  5. 龙架构(LoongArch)赋能众享链网,相关产品已完成适配
  6. 计算机教室规则英语作文,班级规则初中英语作文
  7. 宽窄依赖以及shuffle的部分源码理解
  8. 移动设备上“精灵图”的制作适配
  9. SOLIDWORKS钣金设计需要考虑的折弯问题
  10. 房屋中介信息管理系统