你的浏览器禁用了JavaScript, 请开启后刷新浏览器获得更好的体验!
首页
热门
推荐
精选
登录
|
注册
基于Android的rgb七彩环颜色采集器
立即下载
用AI写一个
金额:
2
元
支付方式:
友情提醒:源码购买后不支持退换货
立即支付
发布时间:2017-11-02
55人
|
浏览:6046次
|
收藏
|
分享
技术:android安卓开发+十六进制颜色与rgb颜色转换
运行环境:androidStudio2.2+jdk8.0
概述
仅仅一个类完成一个自定义颜色采集器view,你可以适用于颜色采集方面的需求,简单大方,demo源码有使用方法与注释。
详细
### 一、前言。 在大学期间,看到这个rgb灯,蛮好奇的,这么漂亮的颜色采集,并且可以同步到设备rbg灯颜色,甚是不解!这个谜团一直在心中困惑。 越是好奇,越是扬起袖子就是干!于是乎,自己结合自己的开发经验和网上开源的代码,进一步的剖析原理,把分析过程一一展现给大家。 ---------- ![这里写图片描述](/contentImages/image/rep/OFMM7VCq0cotb7QiPQJ.jpg) ---------- #### 特性: - 支持采集效果为十六进制的输出与支持十六进制的输入设置圆环颜色。 **比如 #ee1313 红色** - 支持采集效果为十进制的输出与支持十进制的输入设置圆环颜色。 **比如 -16764673 蓝色** #### 方法说明: | 方法 | 说明|参数说明| |-------|------|------| | setSeekBarColorPickerChangeListener() | 色环的颜色值改变时候回调方法|color:十进制颜色 ,htmlRgb:十六进制的颜色| | setColorByhtmlRGB()| 通过十六进制设置色环颜色 |十六进制| | setColorByInt()| 通过十进制设置色环颜色 |十进制| | setGizwitLight()| 设置采集方式为机智云灯 |ture则开启,fasle不开启。默认不开启。毕竟机智云社区的灯的rgb控制范围0到254| ---------- #### 效果图: ---------- ![这里写图片描述](https://camo.githubusercontent.com/35b02ac3fc5c1d12403bb96c68be72c1447c2fc1/687474703a2f2f68357875686f6e672e6f73732d636e2d686f6e676b6f6e672e616c6979756e63732e636f6d2f626c6f674353444e2f453232464231363331374643423935383033434342383044434136314344354673732e706e67) ---------- ### 二、绘图步骤: ---------- 绘图原理: ---------- ![这里写图片描述](/contentImages/image/rep/CitINVs0vtZpSiHWJ4V.jpg) ---------- 绘图步骤: ---------- ![这里写图片描述](/contentImages/image/rep/o8cNPZXxcXX8ncsWadN.jpg) ---------- #### 特性: - 支持采集效果为十六进制的输出与支持十六进制的输入设置圆环颜色。 **比如 #ee1313 红色** - 支持采集效果为十进制的输出与支持十进制的输入设置圆环颜色。 **比如 -16764673 蓝色** #### 方法说明: | 方法 | 说明|参数说明| |-------|------|------| | setSeekBarColorPickerChangeListener() | 色环的颜色值改变时候回调方法|color:十进制颜色 ,htmlRgb:十六进制的颜色| | setColorByhtmlRGB()| 通过十六进制设置色环颜色 |无| | setColorByInt()| 通过十进制设置色环颜色 |无| | setGizwitLight()| 设置采集方式为机智云灯 |ture则开启,fasle不开启。因为机智云的默认定义rgb范围 0到254| ---------- #### 第一步:先画圆环和内部圆。 ---------- - 具体的自定义画圆的步骤大家都熟悉。**画笔、测量。** - 画笔初始化不必多说,强调下渐变色环画笔的stytle属性;还有渐变色环通过SweepGradient类实现。 > Paint.Style.STROKE : 只绘制图形轮廓(描边), **通常的圆环设置这个属性**。 Paint.Style.FILL : 只绘制图形内容 。 Paint.Style.FILL_AND_STROKE : 既绘制轮廓也绘制内容。 ``` //circleX 渲染中心点x坐标,circleY渲染中心y点坐标;mCircleColors为渐变颜色内容 Shader s = new SweepGradient(circleX, circleY, mCircleColors, null); paintCircleRing.setShader(s); ``` - 测量:取整个父布局的view的宽和高,对比取最小一个,保证了半径可以被整个view包裹。 ---------- ``` //圆环的画笔 private Paint paintCircleRing; //最里面的圆的画笔,默认是绿色 private Paint paintInnerColor; //渐变色环参数:红、紫、蓝、绿、黄、橙、红 private final int[] mCircleColors = new int[]{0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00, 0xFFFFFF00, 0xFFFF0000}; //初始化画笔,构造方法调用。 private void init() { // 渐变色环参数 paintCircleRing = new Paint(Paint.ANTI_ALIAS_FLAG); paintCircleRing.setAntiAlias(true); paintCircleRing.setStyle(Paint.Style.STROKE); paintCircleRing.setStrokeWidth(30); //内圆参数 paintInnerColor = new Paint(); paintInnerColor.setColor(Color.GREEN); paintInnerColor.setAntiAlias(true); paintInnerColor.setStrokeWidth(5); } ``` 效果: ---------- ![这里写图片描述](/contentImages/image/rep/lB2ZcTG1ZwKJkrW2iF0.jpg) ---------- #### 三、画圆形图片选择器。 ---------- - 1、 已知圆环的半径**outerRadius **和原点的坐标 **(circleX , circleY) **,通过博文的第一个原理图可得选择器坐标: ``` //选择器x坐标 markPointX = (float) (circleX + outerRadius * Math.sin(angle * Math.PI / 180)); //选择器y坐标 markPointY = (float) (circleY - outerRadius * Math.cos(angle * Math.PI / 180)); ``` ---------- - 2、 画圆点选择器(下图的左边): ---------- ![这里写图片描述](/contentImages/image/rep/3rjDFoDR2Hhhwf9Rt9K.jpg) - frameRadius 半径就是外圆半径减去OC的长度除于2; ---------- ``` canvas.drawCircle(markPointX, markPointY, frameRadius, paintSelecter); ``` ---------- #### 四、颜色求角度。 ---------- - 毋庸置疑,当先从颜色十六进制拿出R、G、B颜色和色环的颜色对比得到结论。 ---------- ``` private float fromColor2Degree(int color) { float degree = 0; int diff = 360 / (mCircleColors.length - 1); int r = Color.red(color); int g = Color.green(color); int b = Color.blue(color); int[] mColor = {b, g, r}; // 把最大的,置0xFF,最小的,置0 int min = findMin(b, g, r); int max = findMax(b, g, r); int temp = (0xff << (max * 8)) + (0xff << (8 * 3)); if (max == min) {//证明RGB相等; return 90;// 九十度 } int mid = 3 - max - min; int start = 0; int end = 0; for (int i = 0; i < mCircleColors.length - 2; i++) { if (mCircleColors[i] - temp == 0) start = i; if (mCircleColors[i] - temp == (0xff << (mid * 8))) end = i; } float percent = (float) mColor[mid] / (float) 0xff; int degreeDiff = (int) (percent * diff); if (start < end) { degree = start * diff; degree += degreeDiff; } else { degree = start * diff; degree -= degreeDiff; } degree += 90; if (degree > 360) degree -= 360; return degree; } ``` ---------- #### 五、角度求颜色。 ---------- ``` //获取圆环上颜色 private int interpCircleColor(int colors[], float degree) { degree -= 90; if (degree < 0) degree += 360; float p = degree * (colors.length - 1) / 360; int i = (int) p; p -= i; int c0 = colors[i]; int c1 = colors[i + 1]; int a = ave(Color.alpha(c0), Color.alpha(c1), p ); int r = ave(Color.red(c0), Color.red(c1), p); int g = ave(Color.green(c0), Color.green(c1), p); int b = ave(Color.blue(c0), Color.blue(c1), p); return Color.argb(a, r, g, b); } ``` ---------- #### 六、点击事件。 ---------- - 这部分不难理解,只要把触摸点的坐标和小圆点的坐标做对比处理,只要是在其周围60dp周围,就认为是触摸到了小圆点选择器。 ---------- ``` private boolean isMarkPointRange(float x, float y) { float range = dp2px(getContext(), 60); return x > (markPointX - range) && x < (markPointX + range) && y > (markPointY - range) && y < (markPointY + range); } ``` ---------- #### 七、view的点击事件传递。 ---------- - 当用户按下手指的位置在圆点周围时候就拦截,否则不拖动小圆点。 - - getParent().requestDisallowInterceptTouchEvent(true); ---------- ``` @Override public boolean onTouchEvent(MotionEvent event) { float markRange = dp2px(getContext(), 60); float x = event.getX(); float y = event.getY(); boolean up = false; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //当用户按下手指的位置在圆点周围时候就拦截 if (x < markPointX + markRange && x > markPointX - markRange && y > markPointY - markRange && y < markPointY + markRange) { getParent().requestDisallowInterceptTouchEvent(true); } moved(x, y, up); break; case MotionEvent.ACTION_MOVE: moved(x, y, up); break; case MotionEvent.ACTION_UP: up = true; moved(x, y, up); break; //当用户取消的手势,就不滑动了 case MotionEvent.ACTION_CANCEL: getParent().requestDisallowInterceptTouchEvent(false); up = true; moved(x, y, up); break; } return true; } ``` ---------- #### 八、小圆点的拖动。 ---------- ``` private void moved(float x, float y, boolean up) { //判断触摸点是否在圆环内 if (!isMarkPointRange(x, y)) { return; } float distance = (float) Math.sqrt(Math.pow((x - circleX), 2) + Math.pow((y - circleY), 2)); if (distance < outerRadius + 100 && distance > innerRadius - 100 && !up) { markPointX = (float) (circleX + outerRadius * Math.cos(Math.atan2(x - circleX, circleY - y) - (Math.PI / 2))); markPointY = (float) (circleY + outerRadius * Math.sin(Math.atan2(x - circleX, circleY - y) - (Math.PI / 2))); float degrees = (float) ((float) ((Math.toDegrees(Math.atan2(x - circleX, circleY - y)) + 360.0)) % 360.0); // 注意:为负数要加360° if (degrees < 0) { degrees += 2 * Math.PI; } //改变内部圆的颜色 int CircleColor = interpCircleColor(mCircleColors, degrees); paintInnerColor.setColor(CircleColor); //角度四舍五入 this.angle = Math.round(degrees); invalidate(); } else { if (mSeekBarColorPickerChangeListener != null) { mSeekBarColorPickerChangeListener.onProgressChange(this, paintInnerColor.getColor()); } invalidate(); } } ``` #### 九、项目文件截图。 ![](/contentImages/image/20171102/iGySTPp3DE55Plh2sFK.png) ----------
本实例支付的费用只是购买源码的费用,如有疑问欢迎在文末留言交流,如需作者在线代码指导、定制等,在作者开启付费服务后,可以点击“购买服务”进行实时联系,请知悉,谢谢
感谢
0
手机上随时阅读、收藏该文章 ?请扫下方二维码
相似例子推荐
评论
作者
半颗心脏
13
例子数量
740
帮助
127
感谢
评分详细
可运行:
4.5
分
代码质量:
4.5
分
文章描述详细:
4.5
分
代码注释:
4.5
分
综合:
4.5
分
作者例子
基于Android的rgb七彩环颜色采集器
企业者的福音之8266接入阿里智能,点亮一盏灯。
乐鑫esp8266的 基于Nonos移植红外线1883,实现遥控器控制
Android开发SDK接入机智云,智能家居实现APP远程控制多设备
实现乐鑫esp8266的无线OTA升级,实现远程在线升级固件。
乐鑫esp8266基于freeRtos实现私有服务器本地远程OTA升级
乐鑫esp8266的串口通讯驱动源文件,nonos和rtos版本
esp8266烧录Html文件,实现内置网页控制设备!
动起来做一个微信小程序Mqtt协议控制智能硬件的框架,支持短线重连!
乐鑫esp8266使用 SPI 驱动Max7219芯片的驱八位数码管!
在支付宝小程序上websocket实现mqtt协议连接服务器控制硬件。
乐鑫esp32 sdk编程驱动ws2812灯珠,实现彩虹光彩夺目效果。
微信小程序ble蓝牙控制esp32,实现无需网络也可以控制亮度;