一个非常不错的颜色圆环选择器视图,由于项目需要自己写了一个圆环颜色选择器,部分代码来源与网络,如有相同敬请谅解。废话不多说,直接上源代码:
1、在values下创建一个attr.xml文件,用于定义视图的xml属性:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="RingColorPicker">
<!--默认角度-->
<attr name="angle" format="float"/>
<!--圆形选择器填充色-->
<attr name="markBackground" format="color|reference"/>
<!--圆形选择器边框颜色-->
<attr name="markStrokeColor" format="color|reference"/>
<!--圆形选择器描边-->
<attr name="isMarkStroke" format="boolean"/>
<!--圆环宽度-->
<attr name="ringWidth" format="dimension"/>
<!--选择器自动色-->
<attr name="isMarkAutoColor" format="boolean"/>
<!--扩散特效透明度-->
<attr name="spreadAlpha" format="integer"/>
<!--选择器描边宽度-->
<attr name="markStrokeWidth" format="dimension|reference"/>
<!--中心按钮图像资源-->
<attr name="srcCompat" />
<!--中心按钮图像透明度-->
<attr name="centerImageAlpha" format="integer"/>
<!--中心复选状态-->
<attr name="checked" format="boolean"/>
<!--当前指向的颜色-->
<attr name="currentColor" format="color|reference"/>
<!--过滤颜色-->
<attr name="tint" />
<!--视图样式-->
<attr name="colorPickerStyle" format="enum">
<enum name="MARK_RING_INNER" value="0"/>
<enum name="MARK_RING_OUTER" value="1"/>
<enum name="MARK_RING_DOWN_OUTER" value="2"/>
</attr>
</declare-styleable>
</resources>
2、这里面使用到了一个自定义颜色工具类来替换Color类,在Color类的基础上增加了部分转换,代码如下:
import android.graphics.Color;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorLong;
import androidx.annotation.IntRange;
import androidx.annotation.Size;
/**
* 颜色工具
*/
public class ColorUnit extends Color {
public ColorUnit(){
super();
}
/**
* 将RGB组件转换为HSV。
* <ul>
* <li>hsv[0]是色调([0..360[)</li>
* <li>hsv[1]已饱和\([0…1]\)</li>
* <li>hsv[2]是值\([0…1]\)</li>
* </ul>
* @param red 红色分量值([0..255])
* @param green 绿色分量值([0..255])
* @param blue 蓝色分量值([0..255])
* @param hsv 3元素数组,用于保存生成的HSV组件。
*/
public static void RGBToHSV(int red,int green, int blue,@Size(3) float hsv[]){
Color.RGBToHSV(red,green,blue,hsv);
}
/**
* 将RGB组件转换为HSV。
* <ul>
* <li>hsv[0]是色调([0..360[)</li>
* <li>hsv[1]已饱和([0…1]\)</li>
* <li>hsv[2]是值([0…1]\)</li>
* </ul>
* @param red 红色的分量([0..1])
* @param green 绿色的分量([0..1])
* @param blue 蓝色的分量([0..1])
* @param hsv 3元素数组,用于保存生成的HSV组件。
*/
public static void RGBToHSV(float red, float green, float blue, @Size(3) float hsv[]){
if(red<0) {
red = 0;
}else if(red>1){
red = 1;
}
if(green<0) {
green = 0;
}else if(green>1){
green = 1;
}
if(blue<0) {
blue = 0;
}else if(blue>1){
blue = 1;
}
Color.RGBToHSV((int)(red*255.0f),(int)(green*255.0f),(int)(blue*255.0f),hsv);
}
/**
* 将HSV组件转为RGB组件
* @param hsv 3元素数组。
* <ul>
* <li>hsv[0]是色调([0..360[)</li>
* <li>hsv[1]色饱和([0…1]\)</li>
* <li>hsv[2]是值([0…1]\)</li>
* </ul>
* @param rgb 3元素数组,用于保存生成的HSV组件。
* <ul>
* <li>rgb[0]颜色的红色分量([0..1])</li>
* <li>rgb[1] 颜色的绿色分量([0..1])</li>
* <li>rgb[2] 颜色的蓝色量([0..1])</li>
* </ul>
*/
public static void HSVToRGB(float hsv[], @Size(3) float rgb[]){
int color=Color.HSVToColor(hsv);
rgb[0]=Color.red(color);
rgb[1]=Color.green(color);
rgb[2]=Color.blue(color);
// Color.colorToHSV();
}
/**
* 将HSV组件转为RGB组件
* @param hue 是色调([0..360[)
* @param saturation 色饱和([0…1]\)
* @param value 亮度值([0…1]\)
* @param rgb 3元素数组,用于保存生成的HSV组件。
* <ul>
* <li>rgb[0]颜色的红色分量([0..1])</li>
* <li>rgb[1] 颜色的绿色分量([0..1])</li>
* <li>rgb[2] 颜色的蓝色量([0..1])</li>
* </ul>
*/
public static void HSVToRGB(float hue,float saturation,float value, @Size(3) float rgb[]){
float hsv[]={
hue,saturation,value};
HSVToRGB(hsv,rgb);
}
/**
* 将HSV组件转换为ARGB颜色。Alpha设置为0xFF。
* @param hue 色调([0..360[)
* @param saturation 色饱和([0…1]\)
* @param value 亮度值([0…1]\)
* @return Argb颜色
*/
public static int HSVToColor(float hue,float saturation,float value){
float hsv[]={
hue,saturation,value};
return Color.HSVToColor(hsv);
}
/**
* 将HSV组件转换为ARGB颜色。alpha分量通过不变。
* @param alpha 返回的argb颜色的alpha分量。
* @param hue 色调([0..360[)
* @param saturation 色饱和([0…1]\)
* @param value 亮度值([0…1]\)
* @return Argb颜色
*/
public static int HSVToColor(@IntRange(from = 0, to = 255) int alpha,float hue,float saturation,float value){
float hsv[]={
hue,saturation,value};
return Color.HSVToColor(alpha,hsv);
}
/**
* 从范围([0..1])内的alpha、red、green、blue float组件返回一个颜色int。如果组件超出范围,则返回的颜色未定义。
* @param alpha 颜色的Alpha分量([0..1])
* @param red 颜色的红色分量([0..1])
* @param green 颜色的绿色分量([0..1])
* @param blue 颜色的蓝色量([0..1])
* @return
*/
@ColorInt
public static int argb(float alpha, float red, float green, float blue){
if(alpha<0) {
alpha = 0;
}else if(alpha>1){
alpha = 1;
}
if(red<0) {
red = 0;
}else if(red>1){
red = 1;
}
if(green<0) {
green = 0;
}else if(green>1){
green = 1;
}
if(blue<0) {
blue = 0;
}else if(blue>1){
blue = 1;
}
return ((int) (alpha * 255.0f + 0.5f) << 24) |
((int) (red * 255.0f + 0.5f) << 16) |
((int) (green * 255.0f + 0.5f) << 8) |
(int) (blue * 255.0f + 0.5f);
}
/**
* 从范围([0..1])内的红色、绿色、蓝色浮点组件返回一个颜色int。alpha组件隐式地为1.0(完全不透明)。如果组件超出范围,则返回的颜色未定义。
* @param red 颜色的红色分量([0..1])
* @param green 颜色的绿色分量([0..1])
* @param blue 颜色的蓝色量([0..1])
* @return
*/
@ColorInt
public static int rgb(float red, float green, float blue) {
if(red<0) {
red = 0;
}else if(red>1){
red = 1;
}
if(green<0) {
green = 0;
}else if(green>1){
green = 1;
}
if(blue<0) {
blue = 0;
}else if(blue>1){
blue = 1;
}
return 0xff000000 |
((int) (red * 255.0f + 0.5f) << 16) |
((int) (green * 255.0f + 0.5f) << 8) |
(int) (blue * 255.0f + 0.5f);
}
/**
* 返回以指定颜色长度编码的红色组件。返回值的范围取决于与指定颜色关联的颜色空间。可以通过调用{@link #colorSpace(long)}来查询颜色空间。
* @param color 要提取其红色通道的长颜色
* @return 具有由指定颜色的颜色空间定义的范围的浮点值
*
* @see #colorSpace(long)
* @see #green(long)
* @see #blue(long)
* @see #alpha(long)
*/
public static float red(@ColorLong long color) {
if ((color & 0x3fL) == 0L) return ((color >> 48) & 0xff) / 255.0f;
return toFloat((short) ((color >> 48) & 0xffff));
}
/**
* 返回以指定颜色长度编码的绿色组件。返回值的范围取决于与指定颜色关联的颜色空间。可以通过调用{@link #colorSpace(long)}来查询颜色空间。
* @param color 要提取其绿色通道的长颜色
* @return 具有由指定颜色的颜色空间定义的范围的浮点值
* @see #colorSpace(long)
* @see #red(long)
* @see #blue(long)
* @see #alpha(long)
*/
public static float green(@ColorLong long color) {
if ((color & 0x3fL) == 0L) return ((color >> 40) & 0xff) / 255.0f;
return toFloat((short) ((color >> 32) & 0xffff));
}
/**
* 返回以指定颜色长度编码的蓝色组件。返回值的范围取决于与指定颜色关联的颜色空间。可以通过调用{@link #colorSpace(long)}来查询颜色空间。
*
* @param color 要提取其蓝色通道的长颜色
* @return 具有由指定颜色的颜色空间定义的范围的浮点值
* @see #colorSpace(long)
* @see #red(long)
* @see #green(long)
* @see #alpha(long)
*/
public static float blue(@ColorLong long color) {
if ((color & 0x3fL) == 0L) return ((color >> 32) & 0xff) / 255.0f;
return toFloat((short) ((color >> 16) & 0xffff));
}
/**
* 返回以指定颜色长度编码的alpha组件。返回的值始终在范围([0..1])内。
* @param color 要提取其alpha通道的长颜色
* @return 范围为([0..1])的浮点值
* @see #colorSpace(long)
* @see #red(long)
* @see #green(long)
* @see #blue(long)
*/
public static float alpha(@ColorLong long color) {
// int c=Color.toArgb(color);
if ((color & 0x3fL) == 0L) return ((color >> 56) & 0xff) / 255.0f;
return ((color >> 6) & 0x3ff) / 1023.0f;
}
/**
* 将指定的长颜色转换为ARGB整型颜色。整型颜色始终位于{@link color space.Named#SRGB SRGB}颜色空间中。这意味着如果需要,将应用颜色空间转换。
* @param color 要转换的长颜色
* @return sRGB颜色空间中的ARGB颜色
*/
@ColorInt
public static int toArgb(@ColorLong long color) {
if ((color & 0x3fL) == 0L) return (int) (color >> 32);
float r = red(color);
float g = green(color);
float b = blue(color);
float a = alpha(color);
return ((int) (a * 255.0f + 0.5f) << 24) |
((int) (r * 255.0f + 0.5f) << 16) |
((int) (g * 255.0f + 0.5f) << 8) |
(int) (b * 255.0f + 0.5f);
}
/**
* 按指定透明度重新输出
* @param color 需要转换的颜色
* @param alpha 透明度
* @return 返回指定透明度的新颜色
*/
public static int toColor(int color,float alpha){
float red=Color.red(color)/255.0f;
float green=Color.green(color)/255.0f;
float blue=Color.blue(color)/255.0f;
return argb(alpha,red,green ,blue );
}
/**
* 按指定透明度重新输出
* @param color 需要转换的颜色
* @param alpha 透明度0-255
* @return 返回指定透明度的新颜色
*/
public static int toColor(int color,int alpha){
return argb(alpha,red(color