Android 颜色选择器 自定义漂亮色环 提供事件回调
先上效果图:
先来啰嗦几句,哈哈哈
此控件真是一波三折啊,算了,还是直接说最终代码流程吧
先说使用流程:
1.XML配置
<com.zhuoapp.opple.view.ColorTouchView android:id="@+id/color_view" android:layout_width="wrap_content" android:layout_height="wrap_content" />
2.UI绑定事件,是不是很简单
mColorView.setOnColorViewTouchListener(new OnColorViewTouchListener() {@Override public void onUpEvent(final int color) {}@Override public void onMoveEvent(int color) {}@Override public void onDownEvent(int color) { }@Override public void onCancelEvent(int color) { } });
3.整个类源码如下
public class ColorTouchView extends View {// 画笔抗锯齿 public Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);// 渐变色环画笔 public Paint mPaintLoc = new Paint(Paint.ANTI_ALIAS_FLAG);// public Paint mPaintFilter = new Paint(Paint.ANTI_ALIAS_FLAG);// // 三十六个色相RGB值,存放默认HSL转化来的RGB值 // (H对应360度平分36份的点,S对应为饱和度[默认为0.5],L对应为亮度[默认为0.5]) public int[] mCircleColors = new int[36];private int alpha = 255;public Shader s;private RadialGradient radialGradient;public int num = 36;public int[] colorArray = new int[num];public int currColor = Color.argb(255, 235, 235, 235);private int borderColor = Color.parseColor("#aeaeae");private int pointColor = Color.parseColor("#ffffff");// 取色圆的初始位置为颜色盘的最右侧 public int x_touchCircle;// 初始化取色圆的圆心的x坐标为宽度的90% public int y_touchCircle;// 初始化取色圆的圆心的y坐标为高度的50% // 小圆半径 public int r_touchCircle = dip2px(6);public int touchAreaDis = dip2px(20);public int height; // 屏幕高度 public int width;// 屏幕宽度 public int step = 0;// 绘制次数 public int Rmax;// 最大半径为宽度的40% public int Rmin;// 最小半径为宽度的26.1955%(经过计算) private static int x_circle, y_circle;private RectF mRectF;private long lastTouchUpTime, currTouchDownTime;private Context mContext;public ColorTouchView(Context context, AttributeSet attrs) {super(context, attrs);this.mContext = context;}protected void onDraw(Canvas canvas) {super.onDraw(canvas);if (x_touchCircle == 0)x_touchCircle = (int) (width * 0.9);if (y_touchCircle == 0)y_touchCircle = (int) (height * 0.5);calLocation();// for (int j = 0; j < step; j++) { int j = 0;for (int w = 0; w < num - 1; w++) {colorArray[w] = ColorUtil.HSL2RGB(new double[]{360.0 / num * w, 1 - 0.6 / step * j, 1});}colorArray[num - 1] = colorArray[0];for (int i = 0; i < num; i++) {mCircleColors[i] = Color.argb(alpha, Color.red(colorArray[i]),Color.green(colorArray[i]), Color.blue(colorArray[i]));}s = new SweepGradient(x_circle, y_circle, mCircleColors, null);mPaint.setShader(s);canvas.drawCircle(x_circle, y_circle, Rmax - step / 2, mPaint);//画外部轮廓 canvas.drawCircle(x_circle,y_circle,Rmax+r_touchCircle/2,mPaintLoc); // } //画透明度 canvas.drawCircle(x_circle, y_circle, Rmax - step / 2, mPaintFilter);mPaint.setColor(borderColor);// 画外部轮廊 canvas.drawCircle(x_circle, y_circle, Rmax, mPaintLoc);// 画内部轮廊 canvas.drawCircle(x_circle, y_circle, Rmin, mPaintLoc);// canvas.drawBitmap(((BitmapDrawable) gd).getBitmap()); // 画圆点 mPaint.setColor(pointColor);mPaintLoc.setStrokeWidth(dip2px(1));if (!touchFlag) {canvas.drawCircle(x_touchCircle, y_touchCircle, r_touchCircle,mPaintLoc);}}private boolean touchFlag = false;@Override public boolean onTouchEvent(MotionEvent event) {// 圆心坐标 x_circle = (int) (width * 0.5);y_circle = (int) (height * 0.5);currTouchDownTime = System.currentTimeMillis();// 两次调色时间需要大于400s if (currTouchDownTime - lastTouchUpTime > 400) {// 触摸点 int aimX = (int) event.getX();int aimY = (int) event.getY();double temp = (aimX - x_circle) * (aimX - x_circle)+ (aimY - y_circle) * (aimY - y_circle);double currR = Math.sqrt(temp); // int zone = (int) (currR - Rmin); // 是否色环上 boolean isCir = currR >= Rmin-touchAreaDis && currR <= Rmax +touchAreaDis;switch (event.getAction()) {case MotionEvent.ACTION_DOWN:if (isCir) {touchFlag = true;invalidate();currColor = ColorUtil.position2RGB(aimX, aimY, x_circle,y_circle, Rmax, Rmin);if (onColorViewTouchListener != null) {onColorViewTouchListener.onDownEvent(currColor);}}case MotionEvent.ACTION_MOVE:if (isCir && touchFlag) {currColor = ColorUtil.position2RGB(aimX, aimY, x_circle,y_circle, Rmax, Rmin);if (onColorViewTouchListener != null) {onColorViewTouchListener.onMoveEvent(currColor);}}break;case MotionEvent.ACTION_UP:if (isCir && touchFlag) {currColor = ColorUtil.position2RGB(aimX, aimY, x_circle,y_circle, Rmax, Rmin);if (onColorViewTouchListener != null) {onColorViewTouchListener.onUpEvent(currColor);}}touchFlag = false;setCurrColor(currColor);lastTouchUpTime = System.currentTimeMillis();break;default:break;}}return true;}// 设置初始值 public void setCurrColor(int color) {this.currColor = color;invalidate();}/** * 根据颜色计算位置 */ private void calLocation() {double[] convertedHsl = ColorUtil.RGB2HSL(currColor);double angle = convertedHsl[0];double saturation = convertedHsl[1];// 所在点距内环的距离 double distance = Rmax * saturation - Rmin;distance = distance < 0 ? 0 : distance;distance = distance > (Rmax - Rmin) ? (Rmax - Rmin) : distance;double currColorR = Rmin + distance;if (currColorR > Rmax) {currColorR = Rmax;}double radians = Math.toRadians(angle);x_touchCircle = (int) (currColorR * Math.cos(radians) + width * .5);y_touchCircle = (int) (currColorR * Math.sin(radians) + height * .5);}@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // setMeasuredDimension(getDefaultSize(0, widthMeasureSpec), getDefaultSize(0, heightMeasureSpec)); height = MeasureSpec.getSize(widthMeasureSpec);width = height;Rmax = (int) (width * 0.46);Rmin = (int) (width * 0.46 * .36);step = Rmax - Rmin;int r = Rmax - step / 2;mRectF = new RectF(x_circle - r, y_circle - r, x_circle + r,y_circle + r);x_circle = (int) (width * 0.5);y_circle = (int) (height * 0.5);mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeWidth(step);mPaintLoc.setStyle(Paint.Style.STROKE);// 设置空心 mPaintLoc.setColor(borderColor);mPaintLoc.setStrokeWidth(dip2px(1));int sc = Color.parseColor("#e0FFFFFF");int ec = Color.parseColor("#00ffffff");int startAlpha = Color.alpha(sc);int endAlpha = Color.alpha(ec);int[] colors = new int[Rmax];float[] pos = new float[Rmax];for (int i = 0; i < Rmax; i++) {if (i < Rmin) {colors[i] = Color.TRANSPARENT;} else {pos[i] = (float) Math.sin((i - Rmin + 1) * 1.0f / step);int a = startAlpha - (int) ((startAlpha - endAlpha) * pos[i]);colors[i] = Color.argb(a, Color.red(sc), Color.green(sc), Color.blue(sc));}pos[i] = (i + 1) * 1.0f / Rmax;}radialGradient = new RadialGradient(x_circle, y_circle, Rmax, colors, pos, Shader.TileMode.REPEAT);mPaintFilter.setShader(radialGradient);mPaintFilter.setStyle(Paint.Style.STROKE);mPaintFilter.setStrokeWidth(step);mPaintFilter.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));setMeasuredDimension(widthMeasureSpec, widthMeasureSpec);}/* android.graphics.PorterDuff.Mode.SRC:只绘制源图像 android.graphics.PorterDuff.Mode.DST:只绘制目标图像 android.graphics.PorterDuff.Mode.DST_OVER:在源图像的顶部绘制目标图像 android.graphics.PorterDuff.Mode.DST_IN:只在源图像和目标图像相交的地方绘制目标图像 android.graphics.PorterDuff.Mode.DST_OUT:只在源图像和目标图像不相交的地方绘制目标图像 android.graphics.PorterDuff.Mode.DST_ATOP:在源图像和目标图像相交的地方绘制目标图像,在不相交的地方绘制源图像 android.graphics.PorterDuff.Mode.SRC_OVER:在目标图像的顶部绘制源图像 android.graphics.PorterDuff.Mode.SRC_IN:只在源图像和目标图像相交的地方绘制源图像 android.graphics.PorterDuff.Mode.SRC_OUT:只在源图像和目标图像不相交的地方绘制源图像 android.graphics.PorterDuff.Mode.SRC_ATOP:在源图像和目标图像相交的地方绘制源图像,在不相交的地方绘制目标图像 android.graphics.PorterDuff.Mode.XOR:在源图像和目标图像重叠之外的任何地方绘制他们,而在不重叠的地方不绘制任何内容 android.graphics.PorterDuff.Mode.LIGHTEN:获得每个位置上两幅图像中最亮的像素并显示 android.graphics.PorterDuff.Mode.DARKEN:获得每个位置上两幅图像中最暗的像素并显示 android.graphics.PorterDuff.Mode.MULTIPLY:将每个位置的两个像素相乘,除以255,然后使用该值创建一个新的像素进行显示。结果颜色=顶部颜色*底部颜色/255 android.graphics.PorterDuff.Mode.SCREEN:反转每个颜色,执行相同的操作(将他们相乘并除以255),然后再次反转。结果颜色=255-(((255-顶部颜色)*(255-底部颜色))/255) */ public boolean inOutCircle(float x, float y, float outRadius, float inRadius) {double outCircle = outRadius;double inCircle = inRadius;double fingerCircle = Math.sqrt(x * x + y * y);if (fingerCircle <= outCircle && fingerCircle >= inCircle) {return true;} else {return false;}}private OnColorViewTouchListener onColorViewTouchListener;public void setOnColorViewTouchListener(OnColorViewTouchListener onColorViewTouchListener) {this.onColorViewTouchListener = onColorViewTouchListener;}public interface OnColorViewTouchListener {public void onUpEvent(int color);public void onDownEvent(int color);public void onMoveEvent(int color);public void onCancelEvent(int color);}private int dip2px(float dpValue) {final float scale = getContext().getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);}}
Android 颜色选择器 自定义漂亮色环 提供事件回调相关推荐
- android类中定义颜色,自定义实现简单的Android颜色选择器(附带源码)
在写Android App过程中需要一个简单的颜色选择器,Android自带的ColorPicker和网上的一些ColorPicker都太高端了,都实现了颜色渐变功能,我要的不需要那么复杂,只想提供几 ...
- Android颜色选择器库
2019独角兽企业重金招聘Python工程师标准>>> 如果您需要使用选择颜色的功能的话, 有2个比较好的颜色选择器开源库可以使用: 1.android-ColorPickerPre ...
- android自定义颜色选择器,自定义View:Android 仿 PS 选色板
前言 今天突然发现年前的文章竟然没有写完,略微有点尴尬.今天分享的主题是Android仿PS选色板. 记得我刚开始学习Android的时候,就一直对PS选色板有一种执着,终于在今年找到了理想的解决方案 ...
- ESP32 开发笔记(四)LVGL控件学习 ColorPicker 颜色选择器控件
先看效果,创建一个颜色选择器控件,设置事件回调动态显示当前选择的颜色值 开发板购买链接https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.5 ...
- Android 自定义View取色盘、颜色选择器、可根据颜色值反向定位坐标
前言: 前段时间项目中需要用到色盘取色的功能,百度了许多相关的颜色选择器,发现这方面自定义View例子比较少,有用图片代替色盘的通过bitmap取色,但是只能取色,无法通过颜色值去定位在色盘上的坐标, ...
- Android 自定义View颜色选择器( 条形、水平),使用HSV颜色模型实现取色器并反向定位颜色所在位置
轻松实现一个简单的Android条形水平颜色选择器,可以通过设置颜色值反向定位滑块 Demo地址:https://github.com/DonTiny/ColorPickDemo 效果图: 先贴完整代 ...
- Android上一种用于选择颜色的控件(颜色选择器)
目录 引言 核心代码 控件整体代码 demo 引言 最近在做一个项目时其中有一个需求–自定义灯光颜色.要求通过手机端控制灯光颜色,手机端预设五种颜色及用户可自定义颜色.在百度上搜索找到一个开源的色环控 ...
- 《Android开发卷——自定义日期选择器(二)》
(小米手机) (中兴手机) 在上一篇中,我介绍了一般公司都会自定义时间日期选择器,并结合自己所做的项目给大家参考. 工作实录之<Android开发卷--自定义日期选择器(一)>链接:htt ...
- android简单的颜色选择器制作
前两天需要开发一个蓝牙通信控制灯的颜色的项目,上网找了一个关于颜色选择器制作的帖子. 众所周知,android的控件只完成了基本的功能,对于像颜色选择的功能则需要自定义控件的使用. 网上的帖子主要都是 ...
最新文章
- echarts词云图形状_怎么用Python画出好看的词云图?
- 腾讯云,物联网通信产品,动态注册步骤
- 并行编程——内存模型之缓存一致性
- [Leetcode][第120题][JAVA][三角形最小路径和][动态规划][递归]
- python struct pack解析_Python struct 详解
- SPOJ AMR12B 720
- config userc.php,框架内置Config.php配置
- 计算机安全防范系统维护,安防系统维护与设备维修(全彩)
- hystrix文档翻译之metrics
- 用户故事与敏捷方法笔记---Scrum与用户故事
- 微信推送封面尺寸_微信公众号封面图、正文配图尺寸如何?如何选择、制作?...
- 5W2H 分析法
- That's why you go away
- Android中framework层下添加aidl编译说程序包不存在
- 如何用Mathpix 和 MathType在WPS快速输入数学公式
- Python常见的魔方方法
- ROS1云课→28机器人代价地图配置
- MCU-CPU-GPU-APU系列
- R语言 | 利用tushare获取股票k线、市值、换手率,市盈率等指标
- Java API 访问HA模式下的HDFS集群
热门文章
- access2003安装包百度云_access2003数据库
- 高新技术企业上市要达到的条件
- PTA 7-43 快速求和(误差修正版)
- 11.5 Vue day06 父子组件通信、自定义事件
- Element Plus图标显示使用教程
- 《MySQL 入门教程》第 32 篇 存储过程(二)
- 服务端和客户端的cookie传递
- IOS-datepick
- Vue3官网-可复用组合式API(十四)实例 property(\$slots,\$attrs)、渲染函数render(虚拟节点VNode,h() 参数,使用JavaScript代替模板功能),插件
- UIWindow.h详解