目录

  • 引言
  • 核心代码
  • 控件整体代码
  • demo

引言

最近在做一个项目时其中有一个需求–自定义灯光颜色。要求通过手机端控制灯光颜色,手机端预设五种颜色及用户可自定义颜色。在百度上搜索找到一个开源的色环控件ColorPickerView,可实现颜色的自定义,效果如图1。给客户看了效果后,客户不是很满意,客户想要类似于UI设计中色相环那样的效果,如图2。


既然客户要求了,那就必须得按客户要求来做。开始做,第一步“先百度”。在百度上果真搜到了一个控件可实现色相环的效果,该控件实现的原理时通过在View上加载图片,根据用户手指触控点获取该图片在该像素点的颜色来实现颜色选择的(这个想法挺不错)。但是最终我没有使用该控件,原因如下:
(1)由于某些原因,UI无法提供色相环的图片给我;
(2)CSDN上没有分,没办法下载demo使用demo中的色相环图片,并且demo中的图片不一定符合我的需求;
(3)适配问题,需要在hdpi,xhdpi,xxhdpi等都做不同尺寸的图片,适配起来比较麻烦。
基于以上原因放弃了使用该控件,不过那个控件挺棒的!不能使用开源控件,那就只能自己写了呗,于是我自己做了一个自定义的小控件,在项目中实现效果如图3。做好后展示给客户,符合客户要求。

这个自定义控件我命名为ColorPicker(颜色选择器,百度搜的开源的也有叫这个的)。这个控件的特点:
1.程序员的事情程序员做,不需要UI提供色相环图片,颜色我们可以自己在代码中设置。控件中我预设了一个7环的色相环,如果颜色不符合要求可在代码中自定义颜色;
2.适配多屏幕,控件可根据屏幕密度,用户设置宽高等自适应,适配效果还凑合;
3.环数自定义,每环颜色也可以自定义,不同环颜色数也可以不同;
4.增加颜色选中效果(代码中也有选中音效,被我注释了,后续的代码中可以看到)。

核心代码

控件绘制原理很简单,根据控件的大小计算每一环的环宽,再根据各环的颜色一一绘制。控件触点判断原理与绘制类似,根据触点距离圆心距离求出触点在第几环,再根据触点坐标求出触点角度,根据角度判断触点选中的颜色,核心代码如下。
通过继承onMeasure方法,根据控件大小求出颜色色块大小及整体圆半径;

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubint widthMode = MeasureSpec.getMode(widthMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);float density = getScreenDensity();int defaultWidth = (int) (DEFAULT_WIDTH_DP * density);int defaultHeight = (int) (DEFAULT_HEIGHT_DP * density);if (widthMode == MeasureSpec.UNSPECIFIED|| widthMode == MeasureSpec.AT_MOST) {widthMeasureSpec = MeasureSpec.makeMeasureSpec(defaultWidth,MeasureSpec.EXACTLY);mWidth = defaultWidth;} else {mWidth = widthSize;}if (heightMode == MeasureSpec.UNSPECIFIED|| heightMode == MeasureSpec.AT_MOST) {heightMeasureSpec = MeasureSpec.makeMeasureSpec(defaultHeight,MeasureSpec.EXACTLY);mHeight = defaultHeight;} else {mHeight = heightSize;}centerX = mWidth / 2;centerY = mHeight / 2;int radius = getBigCircleRadius();/** 计算色块大小*/colorBlockSize = radius / (colorArray.length + 1);super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

(2)根据触点计算选择的颜色

private void computeTouchBlock() {if (touchX == 0 && touchY == 0) {return;}int tmpColorArrId = currentColorArrId;int tmpColorId = currentColorId;double distanceFromCenter = getDistanceFromCenter();if (distanceFromCenter >= getBigCircleRadius()) {return;}/** 计算色环ID*/currentColorArrId = (int) (distanceFromCenter / colorBlockSize);if (currentColorArrId == (colorArray.length + 1)) {currentColorArrId -= 1;}/** 计算当前选中的色块在色环中的位置*/if (currentColorArrId != 0) {String[] colors = colorArray[currentColorArrId - 1];/* 根据当前环颜色数计算角度步长 */int angleStep = 360 / colors.length;int angle = (int) (Math.atan2(touchY - centerY, touchX - centerX) * 180 / Math.PI);angle %= 360;if (angle < -angleStep / 2) {angle += 360;}if (angle > 360 - angleStep / 2) {angle -= 360;}currentColorId = angle / angleStep;}/** 判断选择的色块是否已经改变*/if (tmpColorArrId != currentColorArrId || tmpColorId != currentColorId) {isBlockChanged = true;}if (mListener == null) {return;}/*** 处理颜色监听*/if (currentColorArrId != 0) {String color = colorArray[currentColorArrId - 1][currentColorId];int colorInInt = Color.parseColor(color);if (isRelease) {isRelease = false;mListener.onColorSelected(Color.red(colorInInt),Color.green(colorInInt), Color.blue(colorInInt));} else {mListener.onColorSelecting(Color.red(colorInInt),Color.green(colorInInt), Color.blue(colorInInt));}} else {if (isRelease) {isRelease = false;mListener.onColorSelected(0xff, 0xff, 0xff);} else {mListener.onColorSelecting(0xff, 0xff, 0xff);}}
}

(3)绘制各色相环

private void drawColors(Canvas canvas) {mPaint.setColor(Color.WHITE);mPaint.setStyle(Style.FILL);canvas.drawCircle(centerX, centerY, colorBlockSize, mPaint);for (int colorArrId = 0; colorArrId < colorArray.length; colorArrId++) {String[] colors = colorArray[colorArrId];/* 根据当前环颜色数计算角度步长 */int angleStep = 360 / colors.length;int radius = (colorArrId + 1) * colorBlockSize + colorBlockSize / 2;for (int colorId = 0; colorId < colors.length; colorId++) {int startAngle = -angleStep / 2 + colorId * angleStep;drawColorBlock(canvas, radius, colors[colorId], startAngle,angleStep);}}
}

(4)绘制色块

private void drawColorBlock(Canvas canvas, int radius, String color,int startAngle, int sweepAngle) {mPaint.setStrokeWidth(colorBlockSize);mPaint.setStyle(Style.STROKE);mPaint.setColor(Color.parseColor(color));RectF oval = new RectF(centerX - radius, centerY - radius, centerX+ radius, centerY + radius);canvas.drawArc(oval, startAngle, sweepAngle, false, mPaint);
}

(5)绘制选中效果

private void drawTouchBlock(Canvas canvas) {if (touchX == 0 && touchY == 0) {return;}if (currentColorArrId == 0) {mPaint.setStyle(Style.FILL);mPaint.setColor(Color.parseColor("#33ffffff"));canvas.drawCircle(centerX, centerY, colorBlockSize, mPaint);} else {String[] colors = colorArray[currentColorArrId - 1];/* 根据当前环颜色数计算角度步长 */int angleStep = 360 / colors.length;int radius = (currentColorArrId + 1) * colorBlockSize+ colorBlockSize / 2;int startAngle = -angleStep / 2 + currentColorId * angleStep;drawColorBlock(canvas, radius, "#33ffffff", startAngle, angleStep);}
}

控件整体代码

以上为控件核心代码,控件整体代码如下。

package com.xiaojianya.view;import java.io.FileDescriptor;
import java.io.IOException;import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;/*** 颜色选择器,用于实现色相环颜色选择效果* * @author sk8snow* */
public class ColorPicker extends View {/*** 自定义画笔,用于绘制控件*/private Paint mPaint;/*** 控件高*/
private int mHeight;
/*** 控件宽*/
private int mWidth;
/*** 控件中心点X坐标*/
private int centerX;
/*** 控件中心点Y坐标*/
private int centerY;
/*** 色块大小*/
private int colorBlockSize = 0;
/*** 触摸点X坐标*/
private float touchX = 0;
/*** 触摸点Y坐标*/
private float touchY = 0;/*** 默认大小,使用dp作为单位*/
private static final int DEFAULT_WIDTH_DP = 300;
/*** 默认大小,使用dp作为单位*/
private static final int DEFAULT_HEIGHT_DP = 300;
/*** 选中色相环ID*/
private int currentColorArrId = -1;
/*** 选中环中颜色ID*/
private int currentColorId = -1;
/*** 是否触点释放*/
private boolean isRelease = false;
/*** 是否选择的色块改变*/
private boolean isBlockChanged = false;/*** 色相环颜色值*/
private String[][] colorArray = {{ "#fef5ce", "#fff3cd", "#feeeca", "#fdeac9", "#fee7c7", "#fce3c4","#fbddc1", "#fad7c3", "#fad0c2", "#f2ced0", "#e6cad9","#d9c7e1", "#d2c3e0", "#cfc6e3", "#cac7e4", "#c9cde8","#c7d6ed", "#c7dced", "#c7e3e6", "#d2e9d9", "#deedce","#e7f1cf", "#eef4d0", "#f5f7d0" },{ "#ffeb95", "#fee591", "#fcdf8f", "#fcd68d", "#facd89", "#f9c385","#f7b882", "#f5ab86", "#f29a82", "#e599a3", "#ce93b3","#b48cbe", "#a588be", "#9d8cc2", "#9491c6", "#919dcf","#89abd9", "#85bada", "#86c5ca", "#9fd2b1", "#bada99","#cbe198", "#dde899", "#edf099" },{ "#fee250", "#fed84f", "#fbce4d", "#f9c04c", "#f7b24a", "#f6a347","#f39444", "#f07c4d", "#ec614e", "#d95f78", "#b95b90","#96549e", "#7c509d", "#6e59a4", "#5c60aa", "#5572b6","#3886c8", "#1c99c7", "#0daab1", "#57ba8b", "#90c761","#b0d35f", "#ccdd5b", "#e5e756" },{ "#FDD900", "#FCCC00", "#fabd00", "#f6ab00", "#f39801", "#f18101","#ed6d00", "#e94520", "#e60027", "#cf0456", "#a60b73","#670775", "#541b86", "#3f2b8e", "#173993", "#0c50a3","#0168b7", "#0081ba", "#00959b", "#03a569", "#58b530","#90c320", "#b8d201", "#dadf00" },{ "#DBBC01", "#DAB101", "#D9A501", "#D69400", "#D28300", "#CF7100","#CD5F00", "#CA3C18", "#C7001F", "#B4004A", "#900264","#670775", "#4A1277", "#142E82", "#0A448E", "#005AA0","#0070A2", "#018287", "#02915B", "#4A9D27", "#7DAB17","#9EB801", "#BCC200", "#DBBC01" },{ "#B49900", "#B39000", "#B18701", "#AD7901", "#AB6B01", "#AA5B00","#A84A00", "#A62D10", "#A50011", "#94003C", "#770050","#540060", "#3B0263", "#2B1568", "#10226C", "#053577","#004A87", "#005D88", "#006C6F", "#00784A", "#38831E","#648B0A", "#829601", "#999F01" },{ "#9F8700", "#9E7F00", "#9D7601", "#9A6900", "#995E00", "#975000","#954000", "#932406", "#92000B", "#840032", "#6A0048","#4A0055", "#320057", "#240D5D", "#0C1860", "#032C6A","#014076", "#005278", "#016064", "#006B41", "#2E7316","#567C03", "#718500", "#888D00" } };/*** 颜色选择监听器,设置此监听器用于监听控件中被选择颜色的改变*/
private OnColorSelectedListener mListener;
/*** 颜色选中音效文件*/
private FileDescriptor beepFile;public ColorPicker(Context context) {this(context, null);
}public ColorPicker(Context context, AttributeSet attrs) {super(context, attrs);init();
}/*** 设置色相环颜色* * @param colorArray*            各色相环颜色数组,由内向外依次绘制,索引0绘制于最内侧色环*/
public void setColor(String[][] colorArray) {this.colorArray = colorArray;int radius = getBigCircleRadius();/** 计算色块大小*/colorBlockSize = radius / (colorArray.length + 1);postInvalidate();
}/*** 设置控件颜色选择监听器,用于监听控件选择颜色的改变* * @param listener*            颜色选择监听器*/
public void setOnColorSelectedListener(OnColorSelectedListener listener) {mListener = listener;
}/*** 初始化控件*/
private void init() {mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setDither(true);/** 初始化选中音频文件,若需实现选中音效,去掉此处注释*/
//      beepFile = getAssetsFile(getContext(), "beep.mp3");
}/*** 获取屏幕密度,用于屏幕适配* * @return 屏幕密度*/
private float getScreenDensity() {DisplayMetrics dm = getContext().getResources().getDisplayMetrics();return dm.density;
}@Override
protected void onDraw(Canvas canvas) {// TODO Auto-generated method stubsuper.onDraw(canvas);drawColors(canvas);drawTouchBlock(canvas);/** 播放选中音效,,若需实现选中音效,去掉此处注释*/
//if (isBlockChanged) {
//      playBeep();
//      }}
/*** 从Asset文件夹中读入资源文件* * @param context* @param filename*            资源文件名称* @return*/
private FileDescriptor getAssetsFile(Context context, String filename) {AssetFileDescriptor assetFileDescriptor = null;try {assetFileDescriptor = context.getResources().getAssets().openFd(filename);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}if (assetFileDescriptor != null) {return assetFileDescriptor.getFileDescriptor();} else {return null;}
}// 播放选中音效
private void playBeep() {MediaPlayer mp = new MediaPlayer();try {mp.setDataSource(beepFile);} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalStateException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {mp.prepare();} catch (IllegalStateException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}mp.setOnCompletionListener(new OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mp) {// TODO Auto-generated method stubmp.release();}});mp.start();}/*** 绘制色相环* * @param canvas*/
private void drawColors(Canvas canvas) {mPaint.setColor(Color.WHITE);mPaint.setStyle(Style.FILL);canvas.drawCircle(centerX, centerY, colorBlockSize, mPaint);for (int colorArrId = 0; colorArrId < colorArray.length; colorArrId++) {String[] colors = colorArray[colorArrId];/* 根据当前环颜色数计算角度步长 */int angleStep = 360 / colors.length;int radius = (colorArrId + 1) * colorBlockSize + colorBlockSize / 2;for (int colorId = 0; colorId < colors.length; colorId++) {int startAngle = -angleStep / 2 + colorId * angleStep;drawColorBlock(canvas, radius, colors[colorId], startAngle,angleStep);}}
}/*** 绘制选中效果* * @param canvas*/
private void drawTouchBlock(Canvas canvas) {if (touchX == 0 && touchY == 0) {return;}if (currentColorArrId == 0) {mPaint.setStyle(Style.FILL);mPaint.setColor(Color.parseColor("#33ffffff"));canvas.drawCircle(centerX, centerY, colorBlockSize, mPaint);} else {String[] colors = colorArray[currentColorArrId - 1];/* 根据当前环颜色数计算角度步长 */int angleStep = 360 / colors.length;int radius = (currentColorArrId + 1) * colorBlockSize+ colorBlockSize / 2;int startAngle = -angleStep / 2 + currentColorId * angleStep;drawColorBlock(canvas, radius, "#33ffffff", startAngle, angleStep);}
}/*** 获取触点与圆心的距离* * @return 触点与圆心的距离*/
private double getDistanceFromCenter() {float factor = (touchX - centerX) * (touchX - centerX);factor += (touchY - centerY) * (touchY - centerY);return Math.sqrt(factor);
}@Override
public boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubtouchX = event.getX();touchY = event.getY();switch (event.getAction() & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_UP:isRelease = true;break;case MotionEvent.ACTION_MOVE:break;case MotionEvent.ACTION_DOWN:isRelease = false;break;}isBlockChanged = false;computeTouchBlock();postInvalidate();return true;
}/*** 计算当前选中的色块位置*/
private void computeTouchBlock() {if (touchX == 0 && touchY == 0) {return;}int tmpColorArrId = currentColorArrId;int tmpColorId = currentColorId;double distanceFromCenter = getDistanceFromCenter();if (distanceFromCenter >= getBigCircleRadius()) {return;}/** 计算色环ID*/currentColorArrId = (int) (distanceFromCenter / colorBlockSize);if (currentColorArrId == (colorArray.length + 1)) {currentColorArrId -= 1;}/** 计算当前选中的色块在色环中的位置*/if (currentColorArrId != 0) {String[] colors = colorArray[currentColorArrId - 1];/* 根据当前环颜色数计算角度步长 */int angleStep = 360 / colors.length;int angle = (int) (Math.atan2(touchY - centerY, touchX - centerX) * 180 / Math.PI);angle %= 360;if (angle < -angleStep / 2) {angle += 360;}if (angle > 360 - angleStep / 2) {angle -= 360;}currentColorId = angle / angleStep;}/** 判断选择的色块是否已经改变*/if (tmpColorArrId != currentColorArrId || tmpColorId != currentColorId) {isBlockChanged = true;}if (mListener == null) {return;}/*** 处理颜色监听*/if (currentColorArrId != 0) {String color = colorArray[currentColorArrId - 1][currentColorId];int colorInInt = Color.parseColor(color);if (isRelease) {isRelease = false;mListener.onColorSelected(Color.red(colorInInt),Color.green(colorInInt), Color.blue(colorInInt));} else {mListener.onColorSelecting(Color.red(colorInInt),Color.green(colorInInt), Color.blue(colorInInt));}} else {if (isRelease) {isRelease = false;mListener.onColorSelected(0xff, 0xff, 0xff);} else {mListener.onColorSelecting(0xff, 0xff, 0xff);}}
}/*** 绘制色块* * @param canvas* @param radius*            半径* @param color*            色块颜色* @param startAngle*            开始角度* @param sweepAngle*            覆盖角度*/
private void drawColorBlock(Canvas canvas, int radius, String color,int startAngle, int sweepAngle) {mPaint.setStrokeWidth(colorBlockSize);mPaint.setStyle(Style.STROKE);mPaint.setColor(Color.parseColor(color));RectF oval = new RectF(centerX - radius, centerY - radius, centerX+ radius, centerY + radius);canvas.drawArc(oval, startAngle, sweepAngle, false, mPaint);
}/*** 获取整个色环的半径,取宽和高中最小值的二分之一减去8像素* * @return 色环半径*/
private int getBigCircleRadius() {int radius = mWidth > mHeight ? mHeight / 2 : mWidth / 2;return radius - 8;
}@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubint widthMode = MeasureSpec.getMode(widthMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);float density = getScreenDensity();int defaultWidth = (int) (DEFAULT_WIDTH_DP * density);int defaultHeight = (int) (DEFAULT_HEIGHT_DP * density);if (widthMode == MeasureSpec.UNSPECIFIED|| widthMode == MeasureSpec.AT_MOST) {widthMeasureSpec = MeasureSpec.makeMeasureSpec(defaultWidth,MeasureSpec.EXACTLY);mWidth = defaultWidth;} else {mWidth = widthSize;}if (heightMode == MeasureSpec.UNSPECIFIED|| heightMode == MeasureSpec.AT_MOST) {heightMeasureSpec = MeasureSpec.makeMeasureSpec(defaultHeight,MeasureSpec.EXACTLY);mHeight = defaultHeight;} else {mHeight = heightSize;}centerX = mWidth / 2;centerY = mHeight / 2;int radius = getBigCircleRadius();/** 计算色块大小*/colorBlockSize = radius / (colorArray.length + 1);super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}/*** 颜色选择监听器,用于监听颜色的改变,在选择颜色过程中,当颜色改变时且未释放触点时调用onColorSelecting方法,* 在选择过程中所有被临时选中的颜色* 都将通过onColorSelecting方法回传;当最终选择的颜色确定时,调用onColorSelected,此方法回传最终选择的颜色* * @author sk8snow* */
public interface OnColorSelectedListener {/*** 颜色选中改变,当未释放触点时调用此方法,此方法在选择颜色过程中可能颜色改变时就会被调用,整个过程中会被多次调用,* 但所传值为选择的不同颜色值* * @param red* @param green* @param blue*/public void onColorSelecting(int red, int green, int blue);/*** 颜色选中改变,选中最终颜色,此方法在触点被释放时调用,在选择颜色过程中只会调用一次,所传值为最终选择的颜色值* * @param red* @param green* @param blue*/public void onColorSelected(int red, int green, int blue);
}

}
将以上代码直接复制至项目中可直接使用此控件。

demo

控件demo下载地址,demo中开启了选中音效。控件相关demo代码,布局文件如下:

<com.xiaojianya.view.ColorPickerandroid:id="@+id/color_picker"android:layout_width="200dp"android:layout_height="200dp" /><LinearLayoutandroid:layout_marginTop="16dp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:gravity="center_vertical" ><TextViewandroid:id="@+id/color_value_txt"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginRight="16dp" /><ImageViewandroid:id="@+id/color_indicator"android:layout_width="25dp"android:layout_height="25dp" />
</LinearLayout><Button android:layout_marginTop="16dp"android:id="@+id/change_color_btn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="改变色相环"/>

Activity代码如下:

package com.xiaojianya.colorpickerdemo;import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView;import com.xiaojianya.view.ColorPicker;
import com.xiaojianya.view.ColorPicker.OnColorSelectedListener;public class MainActivity extends Activity implements OnClickListener {private ColorPicker colorPicker;private TextView colorValueTxt;private ImageView colorIndicator;@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();
}private void init(){colorPicker = (ColorPicker)findViewById(R.id.color_picker);colorPicker.setOnColorSelectedListener(new OnColorSelectedListener() {@Overridepublic void onColorSelecting(int red, int green, int blue) {// TODO Auto-generated method stubString value = "红色:" +  red + "\t绿色:" + green + "\t蓝色:" + blue;int color = Color.rgb(red, green, blue);value += "\n颜色值:0x" + Integer.toHexString(color);colorValueTxt.setText(value);colorIndicator.setBackgroundColor(color);}@Overridepublic void onColorSelected(int red, int green, int blue) {// TODO Auto-generated method stubString value = "红色:" +  red + "\t绿色:" + green + "\t蓝色:" + blue;int color = Color.rgb(red, green, blue);value += "\n颜色值:0x" + Integer.toHexString(color);colorValueTxt.setText(value);colorIndicator.setBackgroundColor(color);}});colorValueTxt = (TextView)findViewById(R.id.color_value_txt);colorIndicator = (ImageView)findViewById(R.id.color_indicator);findViewById(R.id.change_color_btn).setOnClickListener(this);
}@Override
public void onClick(View arg0) {// TODO Auto-generated method stubString[][] colorArray = {{ "#fef5ce", "#fff3cd", "#feeeca", "#fdeac9", "#fee7c7", "#fce3c4","#fbddc1", "#fad7c3", "#fad0c2", "#f2ced0", "#e6cad9","#d9c7e1", "#d2c3e0", "#cfc6e3", "#cac7e4", "#c9cde8","#c7d6ed", "#c7dced", "#c7e3e6", "#d2e9d9", "#deedce","#e7f1cf", "#eef4d0", "#f5f7d0" },{ "#ffeb95", "#fee591", "#fcdf8f", "#fcd68d", "#facd89", "#f9c385","#f7b882", "#f5ab86", "#f29a82", "#e599a3", "#ce93b3","#b48cbe", "#a588be", "#9d8cc2", "#9491c6", "#919dcf","#89abd9", "#85bada", "#86c5ca", "#9fd2b1", "#bada99","#cbe198", "#dde899", "#edf099" },{ "#fee250", "#fed84f", "#fbce4d", "#f9c04c", "#f7b24a", "#f6a347","#f39444", "#f07c4d", "#ec614e", "#d95f78", "#b95b90","#96549e", "#7c509d", "#6e59a4", "#5c60aa", "#5572b6","#3886c8", "#1c99c7", "#0daab1", "#57ba8b", "#90c761","#b0d35f", "#ccdd5b", "#e5e756" },{ "#FDD900", "#FCCC00", "#fabd00", "#f6ab00", "#f39801", "#f18101","#ed6d00", "#e94520", "#e60027", "#cf0456", "#a60b73","#670775", "#541b86", "#3f2b8e", "#173993", "#0c50a3","#0168b7", "#0081ba", "#00959b", "#03a569", "#58b530","#90c320", "#b8d201", "#dadf00" },{ "#DBBC01", "#DAB101", "#D9A501", "#D69400", "#D28300", "#CF7100","#CD5F00", "#CA3C18", "#C7001F", "#B4004A", "#900264","#670775", "#4A1277", "#142E82", "#0A448E", "#005AA0","#0070A2", "#018287", "#02915B", "#4A9D27", "#7DAB17","#9EB801", "#BCC200", "#DBBC01" }};colorPicker.setColor(colorArray);}}

Android上一种用于选择颜色的控件(颜色选择器)相关推荐

  1. VC 对话框背景颜色 控件颜色

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 系统环境 ...

  2. android如何绑定事件,Android_安卓为按钮控件绑定事件的五种方式

    一.写在最前面 本次,来介绍一下安卓中为控件--Button绑定事件的五种方式. 二.具体的实现 第一种:直接绑定在Button控件上: 步骤1.在Button控件上设置android:onClick ...

  3. Android入门(二)——常见布局与控件

    文章目录 一.常见界面布局 1.线性布局 LinearLayout 2.相对布局 RelativeLayout 3.表格布局 TableLayout 4.帧布局 FrameLayout 二.常见界面控 ...

  4. Android 自定义View 三板斧之二——组合现有控件

    通常情况下,Android实现自定义控件无非三种方式. Ⅰ.继承现有控件,对其控件的功能进行拓展. Ⅱ.将现有控件进行组合,实现功能更加强大控件. Ⅲ.重写View实现全新的控件 上文说过了如何继承现 ...

  5. Android 第十八课 强大的滚动控件 RecyclerView

    步骤: 一.添加依赖库 compile'com.android.support:recyclerview-v7:26.1.0' 二.在activity_mian.xml中,添加RecyclerView ...

  6. APP国际化、动态设置控件颜色(APP个性化)

    亲身体验:某些时候QQ音乐首页整体都成灰色,艾玛,BUG!!!,截图反馈.只有首页,其他的界面没问题,好家伙,故意的! 确实,今天咱也来搞一下,这篇文章主要记录项目 1. 国际化 2. 动态设置控件颜 ...

  7. android禁止下拉刷新,Android开发之无痕过渡下拉刷新控件的实现思路详解

    相信大家已经对下拉刷新熟悉得不能再熟悉了,市面上的下拉刷新琳琅满目,然而有很多在我看来略有缺陷,接下来我将说明一下存在的缺陷问题,然后提供一种思路来解决这一缺陷,废话不多说!往下看嘞! 1.市面一些下 ...

  8. Android开发之Android Studio 3.6新特性之获取控件id的高级方式ViewBinding

    一般获取id有如下几种方式: 访问布局控件ID方式 优点 缺点 findViewById 系统提供有保障 特别繁琐代码量大 第三方注解 快捷简单 引用三方可能有不确定因素 kotlinx.androi ...

  9. android 360旋转动画,ANDROID——仿360手机卫士的旋转打分控件

    简介 灵感源自360手机卫,主要功能就是实现显示评分或等级的效果.并稍微改良了一下,有更好的实用性和扩展性. 因为主要用途就是显示"分数","评价",所以暂且叫 ...

最新文章

  1. maven项目密码md5加密_加密Spring Boot中的application.properties
  2. 加白名单_【食品加奖学金】宁波大学张鑫团队:青钱柳黄酮对昼夜节律紊乱小鼠的肠道菌群和肝脏时钟基因的调节作用...
  3. 大作完成了一部分,陆续往上放吧
  4. Dell服务器RAID常用管理命令总结 linux
  5. Raspbian 中国软件源
  6. 优化mysql数据库_MySQL数据库十大优化技巧
  7. apache kafka源代码工程环境搭建(IDEA)
  8. linux df 查看磁盘剩余空间,du查看文件占用多少空间,rm -rf 删除文件 mkdir -p创建目录(含父级)
  9. Linux 之shell脚本编程
  10. DSP2812入门2——结构资源性能
  11. linux中括号的用法,【shell】Linux shell中括号的用法
  12. netty(7)--UDP实战
  13. 《军团要塞2》绘画渲染
  14. 需求工程规格说明、需求验证、需求管理
  15. 51nod 1740蜂巢迷宫
  16. 修改未能正确启动的docker容器的配置文件
  17. AppleCare 扫盲帖,三年苹果狗告诉你 AppleCare 到底值不值得买?
  18. 提取字符串中一个或多个空格隔开的字符串
  19. 天翼LifePad抢占3G平板电脑市场
  20. Important Programming Concepts (Even on Embedded Systems) Part V: State Machines

热门文章

  1. 洛谷 P1402 酒店之王
  2. python通过execjs运行js代码
  3. stm32毕设分享 STM32单片机的智能家居环境监测控制系统
  4. 多看一眼多进步,python入门到放弃
  5. 帷幄SDP - 店铺数字化转型 店铺数字化智能营销服务平台
  6. LLM大模型中文开源数据集集锦(三)
  7. 伦敦金行情——几点停盘
  8. 最新款!百度网盘迁移阿里云盘工具,亲测可用!
  9. FreeSql 新的八大骚功能,.NETCore 你必须晓得的 ORM
  10. (b)液晶屏是LVDS接口如何实现点屏?