Android -- [SelfView] 自定义多色渐变背景板

Android – 自定义多色渐变背景板

前言:
Android 自带的 xml 文件内 gradient 设置渐变最多只有三种颜色,使用方便但范围受限,不能很好满足各种需求;
本款多色渐变背景板应运而生:* 1. 支持圆角模式,矩形模式;* 2. 支持线性、扫描和环形渐变,线性渐变支持0-180角度设置;* 3. 支持多种颜色设置;(E.g: #ff0000 #00ff00 #0000ff)

在这里插入图片描述

使用:
//三种效果:
<LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"android:layout_centerInParent="true"><com.nepalese.virgocomponent.view.VirgoGradientViewandroid:layout_width="160dp"android:layout_height="120dp"app:vgMode="mode_rect"app:vgRoundRadius="60dp"app:vgColors="#3f51b1 #5a55ae #7b5fac #8f6aae #a86aa4 #cc6b8e #f18271 #f3a469 #f7c978"app:vgGradientMode="gradient_linear"app:vgLinearAngle="15" /><com.nepalese.virgocomponent.view.VirgoGradientViewandroid:layout_marginStart="20dp"android:layout_width="160dp"android:layout_height="120dp"app:vgMode="mode_round"app:vgRoundRadius="15dp"app:vgColors="#3f51b1 #5a55ae #7b5fac #8f6aae #a86aa4 #cc6b8e #f18271 #f3a469 #f7c978"app:vgGradientMode="gradient_linear"app:vgLinearAngle="30" /><com.nepalese.virgocomponent.view.VirgoGradientViewandroid:layout_marginStart="20dp"android:layout_width="120dp"android:layout_height="120dp"app:vgMode="mode_round"app:vgRoundRadius="60dp"app:vgColors="#3f51b1 #5a55ae #7b5fac #8f6aae #a86aa4 #cc6b8e #f18271 #f3a469 #f7c978"app:vgGradientMode="gradient_linear"app:vgLinearAngle="45" /></LinearLayout>

码源:

1. attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="VirgoGradientView"><attr name="vgMode" format="integer"><enum name="mode_round" value="1"/><enum name="mode_rect" value="2"/></attr><attr name="vgGradientMode" format="integer"><enum name="gradient_linear" value="1"/><enum name="gradient_sweep" value="2"/><enum name="gradient_radial" value="3"/></attr><attr name="vgLinearAngle" format="integer"/><attr name="vgRoundRadius" format="dimension|reference"/><attr name="vgColors" format="string"/></declare-styleable>
</resources>
2. VirgoGradientView.java
package com.nepalese.virgocomponent.view;import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;import androidx.annotation.Nullable;import com.nepalese.virgocomponent.R;/*** @author nepalese on 2024/10/10 10:10* @usage 多色渐变调板:* 1. 支持圆角模式,矩形模式;* 2. 支持线性、扫描和环形渐变,线性渐变支持0-180角度设置;* 3. 支持多种颜色设置;(E.g: #ff0000 #00ff00 #0000ff)*/
public class VirgoGradientView extends View {private static final String TAG = "VirgoGradientView";public static final int MODE_ROUND = 1;//圆角模式public static final int MODE_RECT = 2;//矩形模式(默认)public static final int GRADIENT_LINEAR = 1;//线性渐变public static final int GRADIENT_SWEEP = 2;//扫描渐变public static final int GRADIENT_RADIAL = 3;//环形渐变private Paint mPaint;//画笔private RectF mRectF;//画布矩形private Shader mShader;//渐变渲染private int mWidth, mHeight;//宽高private int mMode;//图形模式private int mGradientMode;//渐变模式private int mAngle;//线性渐变角度(从左->右:0-180)private int mRoundRadius;//圆角半径(仅圆角模式)private int[] mColors;//颜色组public VirgoGradientView(Context context) {this(context, null);}public VirgoGradientView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public VirgoGradientView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init(attrs);}private void init(AttributeSet attrs) {String strColors;//颜色按顺序,以空格间开TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.VirgoGradientView);mMode = typedArray.getInt(R.styleable.VirgoGradientView_vgMode, MODE_RECT);mAngle = typedArray.getInt(R.styleable.VirgoGradientView_vgLinearAngle, 0);mGradientMode = typedArray.getInt(R.styleable.VirgoGradientView_vgGradientMode, GRADIENT_LINEAR);mRoundRadius = typedArray.getDimensionPixelSize(R.styleable.VirgoGradientView_vgRoundRadius, 20);strColors = typedArray.getString(R.styleable.VirgoGradientView_vgColors);typedArray.recycle();mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setDither(true);mPaint.setStyle(Paint.Style.FILL);//初始化默认颜色initColor(strColors);}private void initColor(String strColors) {if (TextUtils.isEmpty(strColors)) {strColors = "#69EACB #EACCF8 #6654F1";//默认}if (strColors.contains(" ")) {String[] colors = strColors.split(" ");mColors = new int[colors.length];for (int i = 0; i < colors.length; i++) {try {mColors[i] = Color.parseColor(colors[i]);} catch (Exception e) {mColors[i] = Color.WHITE;}}} else {//单色mColors = new int[1];try {mColors[0] = Color.parseColor(strColors);} catch (Exception e) {//格式异常Log.e(TAG, "格式异常!");mColors[0] = Color.WHITE;}}//        //彩虹色
//        mColors = new int[7];
//        mColors[0] = Color.rgb(255,0,0);
//        mColors[1] = Color.rgb(255,165,0);
//        mColors[2] = Color.rgb(255,255,0);
//        mColors[3] = Color.rgb(0,255,0);
//        mColors[4] = Color.rgb(0,127,255);
//        mColors[5] = Color.rgb(0,0,255);
//        mColors[6] = Color.rgb(139,0,255);}private void setShader() {switch (mGradientMode) {case GRADIENT_LINEAR://x0,y0,x1,y1是起始位置和渐变的结束位置//positions指定颜色数组的相对位置: [0…1], 如果传null,渐变就线性变化//角度正切值double tan = Math.tan(Math.PI * mAngle / 180);if (45 > mAngle && mAngle >= 0) {//[0,45)mShader = new LinearGradient(0, (float) ((mHeight - tan * mWidth) / 2), mWidth, (float) ((mHeight + tan * mWidth) / 2), mColors, null, Shader.TileMode.CLAMP);} else if (135 >= mAngle && mAngle >= 45) {//[45,135]if (mAngle == 90) {mShader = new LinearGradient(mWidth / 2f, 0, mWidth / 2f, mHeight, mColors, null, Shader.TileMode.CLAMP);} else {mShader = new LinearGradient((float) ((mWidth - mHeight / tan) / 2), 0, (float) ((mWidth + mHeight / tan) / 2), mHeight, mColors, null, Shader.TileMode.CLAMP);}} else if (180 >= mAngle && mAngle > 135) {mShader = new LinearGradient(mWidth, (float) ((mHeight + tan * mWidth) / 2), 0, (float) ((mHeight - tan * mWidth) / 2), mColors, null, Shader.TileMode.CLAMP);} else {//默认左 -> 右mShader = new LinearGradient(0, 0, mWidth, 0, mColors, null, Shader.TileMode.CLAMP);}break;case GRADIENT_SWEEP://cx,cy,圆的中心坐标mShader = new SweepGradient(mWidth / 2f, mHeight / 2f, mColors, null);break;case GRADIENT_RADIAL://cx,cy,中心坐标int max = Math.max(mWidth, mHeight);mShader = new RadialGradient(mWidth / 2f, mHeight / 2f, max / 2f, mColors, null, Shader.TileMode.CLAMP);break;}mPaint.setShader(mShader);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);//在measure之后, layout之前mRectF = new RectF(0, 0, w, h);mWidth = w;mHeight = h;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);setShader();if (mMode == MODE_RECT) {//矩形canvas.drawRect(mRectF, mPaint);} else {//圆角canvas.drawRoundRect(mRectF, mRoundRadius, mRoundRadius, mPaint);}}//api//public void setmMode(int mMode) {this.mMode = mMode;}public void setmGradientMode(int mGradientMode) {this.mGradientMode = mGradientMode;}public void setmAngle(int mAngle) {this.mAngle = mAngle % 180;}public void setmRoundRadius(int mRoundRadius) {this.mRoundRadius = mRoundRadius;}//颜色种类不少于2public void setmColors(int[] mColors) {if (mColors.length < 2) {return;}this.mColors = mColors;}
}

渐变色网站:

https://webgradients.com/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/443774.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows环境下CTRL+C信号处理函数的执行线程

1. 捕获CTRLC 有时候我们希望自己的程序被CTRLC以后&#xff0c;可以先执行一些收尾的工作才结束&#xff0c;比如释放动态内存&#xff0c;关闭网络端口、保存一些状态日志等等&#xff0c;可以用到C的signal的机制。 例程如下&#xff1a; #include <iostream> #inc…

【工具】前端js数字金额转中文大写金额

【工具】前端js数字金额转中文大写金额 代码 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>金额转…

WIFI网速不够是不是光猫的“路由模式”和“桥接模式”配置错了?

光猫&#xff08;光纤调制解调器&#xff09;是一种用于将光纤信号转换为数字信号的设备&#xff0c;通常用于家庭或企业网络中。光猫可以在不同的工作模式下运行&#xff0c;其中最常见的两种模式是“路由模式”和“桥接模式”。以下是这两种模式的详细解释及其优缺点。 一、路…

『网络游戏』服务器向客户端分发消息【20】

对服务器添加System引用 修改脚本&#xff1a;LoginSys.cs 修改脚本&#xff1a;NetSvc.cs 修改脚本&#xff1a;ServerSession.cs 修改脚本&#xff1a;GameMsg.cs 修改脚本&#xff1a;MsgPack.cs 修改脚本&#xff1a;LoginSys.cs 修改脚本&#xff1a;ServerRoot.cs 修改脚…

GAMES101(19节,相机)

相机 synthesis合成成像&#xff1a;比如光栅化&#xff0c;光线追踪&#xff0c;相机是capture捕捉成像&#xff0c; 但是在合成渲染时&#xff0c;有时也会模拟捕捉成像方式&#xff08;包括一些技术 动态模糊 / 景深等&#xff09;&#xff0c;这时会有涉及很多专有名词&a…

探索新境界,尽在Codigger新版官网!

&#x1f389; 重大更新&#xff01; 我们自豪地宣布 Codigger 官网焕然一新&#xff0c;带来前所未有的体验&#xff01; &#x1f31f; 全新界面&#xff1a;Desktop享受更加直观、现代的视觉盛宴&#xff0c;发现 Codigger 的无限可能。 &#x1f680; 增强功能&#xff1…

ThinkPHP5bootstrapMySQL开发学习平台(包括后台管理功能、PC端网页、移动端网页)手把手运行源码

一、项目预览(全部源码链接在最下面) 功能及页面持续优化中...... 二、本地运行方式 1、下载源码包进行解压(源码在最下面) 2、下载phpstudy_pro,并运行Apache&

【Qt】Qt安装(2024-10,QT6.7.3,Windows,Qt Creator 、Visual Studio、Pycharm 示例)

文章目录 一、Qt 简介二、安装开源版本2.1 Qt 官网 与 版本选择2.2 Qt 安装程序 三、使用示例3.1 Qt Creator3.11 示例程序3.12 新建C项目3.13 新建Python项目 3.2 Visual Studio 附录附录 1&#xff1a;Additional Libraries 说明附录2 &#xff1a;老版本安装附录3&#xff1…

Java数据类型常量

目录 一、数据类型 1.1分类 1.2关键字&内存占用&范围 1.3包装类 1.4说明 1.5类型转换 1.6类型提升 二、常量 2.1java中的常量 2.2定义常量 2.3分类 一、数据类型 1.1分类 1.2关键字&内存占用&范围 数据类型关键字内存占用范围字节型byte1字节-128…

使用three.js 实现一个 马赛克得 shader

使用three.js 实现一个 马赛克得 shader 源链接&#xff1a;https://threehub.cn/#/codeMirror?navigationThreeJS&classifyshader&idmosaicShader 国内站点预览&#xff1a;http://threehub.cn github地址: https://github.com/z2586300277/three-cesium-example…

【大数据】数据分析之Spark框架介绍

文章目录 概述一、发展历程与背景二、核心特点三、生态系统与组件四、应用场景五、与其他大数据技术的比较 核心概念1. 弹性分布式数据集&#xff08;RDD, Resilient Distributed Dataset&#xff09;2. 转换&#xff08;Transformations&#xff09;和动作&#xff08;Actions…

【网络篇】计算机网络——应用层详述(笔记)

目录 一、应用层协议原理 1. 进入应用层 2. 网络应用程序体系结构 &#xff08;1&#xff09;客户-服务器体系结构&#xff08;client-server architecture&#xff09; &#xff08;2&#xff09; P2P 体系结构&#xff08;P2P architecture&#xff09; 3. 进程间通讯 …

Java之String类

目录 初识String 字符串比较相等 字符串常量池 理解字符串的不可变 字符与字符串 字符串常见操作 字符串比较 compareTo()函数的原码 字符串查找 字符串替换 字符串拆分 字符串截取 其它操作 StringBuffer和StringBuilder 面试题&#xff1a;请解释String、Strin…

Cocos_鼠标滚轮放缩地图

文章目录 前言一、环境二、版本一_code2.分析类属性方法详细分析详细分析onLoad()onMouseWheel(event)详细分析 总结 前言 学习笔记&#xff0c;请多多斧正。 一、环境 通过精灵rect放置脚本实现鼠标滚轮放缩地图。 二、版本一_code import { _decorator, Component, Node }…

第十一章:规划过程组(11.18规划风险管理--11.24规划干系人参与)

前面几次考试几乎都考了风险管理的相关内容和试题~&#xff01;尤其是下午题所以感觉还是挺重要的&#xff01; 11.18 规划风险管理 11.18.1 风险基本概念 每个项目都在两个层面上存在风险:一是每个项目都有会影响项目达成目标的单个风险;二是由单个风险和不确定性的其他来源联…

一文了解,ARM 工业计算机的发展历程

ARM 工业计算机的发展历程主要经历了以下几个阶段&#xff1a; 早期探索阶段&#xff08;20 世纪 80 年代 - 90 年代初&#xff09;&#xff1a; 起源背景&#xff1a;20 世纪 80 年代&#xff0c;计算机工业蓬勃发展&#xff0c;英国的 Acorn 公司在这一时期积极探索芯片技术…

VRRP协议个人理解+报文示例+典型配置-RFC2338/RFC3768/RFC5798/RFC9568

个人认为&#xff0c;理解报文就理解了协议。通过报文中的字段可以理解协议在交互过程中相关传递的信息&#xff0c;更加便于理解协议。 因此本文将在VRRP协议报文的基础上进行介绍。 VRRP协议发展 关于VRRPv2基本原理&#xff0c;可重点参考2004年发布的RFC3768-Virtual Ro…

Qt5.15.2静态编译 MinGW with static OpenSSL

如果想用VS2017编译,可参考:Qt5.15.2静态编译 VS2017 with static OpenSSL 一.环境 系统:Windows 10 专业版 64位 编译器:MinGW 8.1.0 第三方工具:perl,ruby和python PS:经验证,用MinGW 12.1.0来编译Qt5.15.2会报错 我用Phthon 2.7.18虽然可以编过,但是强烈建议Pyth…

CSS响应式布局

CSS 响应式布局也称自适应布局&#xff0c;是 Ethan Marcotte 在 2010 年 5 月份提出的一个概念&#xff0c;简单来讲就是一个网站能够兼容多个不同的终端&#xff08;设备&#xff09;&#xff0c;而不是为每个终端做一个特定的版本。这个概念是为解决移动端浏览网页而诞生的。…

可以让你干一辈子的10大项目,想赚钱的别错过!

1、卖项目 很多想要创业、或者从事自由职业的小伙伴,都经常会因为找不到合适的项目而苦恼,所以那些即靠谱又赚钱的好项目,一直都是人们的刚性需求,而且还是可持续的需求,倘若谁能解决这个问题,那么自然就可以赚到大钱,毕竟现在原因付费买项目的大有人在! 2、卖技术 掌…