packagecom.dwood.paintdemo;
importAndroid.app.Dialog;
importandroid.content.Context;
importandroid.graphics.Canvas;
importandroid.graphics.Color;
importandroid.graphics.LinearGradient;
importandroid.graphics.Paint;
importandroid.graphics.RectF;
importandroid.graphics.Shader;
importandroid.graphics.SweepGradient;
importandroid.os.Bundle;
importandroid.util.Log;
importandroid.view.MotionEvent;
importandroid.view.View;
importandroid.view.WindowManager;
publicclassColorPickerDialogextendsDialog {
privatefinalbooleandebug =true;
privatefinalString TAG ="ColorPicker";
Context context;
privateString title;//标题
privateintmInitialColor;//初始颜色
privateOnColorChangedListener mListener;
/**
* 初始颜色黑色
* @param context
* @param title 对话框标题
* @param listener 回调
*/
publicColorPickerDialog(Context context, String title,
OnColorChangedListener listener) {
this(context, Color.BLACK, title, listener);
}
/**
*
* @param context
* @param initialColor 初始颜色
* @param title 标题
* @param listener 回调
*/
publicColorPickerDialog(Context context,intinitialColor,
String title, OnColorChangedListener listener) {
super(context);
this.context = context;
mListener = listener;
mInitialColor = initialColor;
this.title = title;
}
@Override
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WindowManager manager = getWindow().getWindowManager();
intheight = (int) (manager.getDefaultDisplay().getHeight() *0.5f);
intwidth = (int) (manager.getDefaultDisplay().getWidth() *0.7f);
ColorPickerView myView =newColorPickerView(context, height, width);
setContentView(myView);
setTitle(title);
}
privateclassColorPickerViewextendsView {
privatePaint mPaint;//渐变色环画笔
privatePaint mCenterPaint;//中间圆画笔
privatePaint mLinePaint;//分隔线画笔
privatePaint mRectPaint;//渐变方块画笔
privateShader rectShader;//渐变方块渐变图像
privatefloatrectLeft;//渐变方块左x坐标
privatefloatrectTop;//渐变方块右x坐标
privatefloatrectRight;//渐变方块上y坐标
privatefloatrectBottom;//渐变方块下y坐标
privatefinalint[] mCircleColors;//渐变色环颜色
privatefinalint[] mRectColors;//渐变方块颜色
privateintmHeight;//View高
privateintmWidth;//View宽
privatefloatr;//色环半径(paint中部)
privatefloatcenterRadius;//中心圆半径
privatebooleandownInCircle =true;//按在渐变环上
privatebooleandownInRect;//按在渐变方块上
privatebooleanhighlightCenter;//高亮
privatebooleanhighlightCenterLittle;//微亮
publicColorPickerView(Context context,intheight,intwidth) {
super(context);
this.mHeight = height -36;
this.mWidth = width;
setMinimumHeight(height -36);
setMinimumWidth(width);
//渐变色环参数
mCircleColors =newint[] {0xFFFF0000,0xFFFF00FF,0xFF0000FF,
0xFF00FFFF,0xFF00FF00,0xFFFFFF00,0xFFFF0000};
Shader s =newSweepGradient(0,0, mCircleColors,null);
mPaint =newPaint(Paint.ANTI_ALIAS_FLAG);
mPaint.setShader(s);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(50);
r = width /2*0.7f - mPaint.getStrokeWidth() *0.5f;
//中心圆参数
mCenterPaint =newPaint(Paint.ANTI_ALIAS_FLAG);
mCenterPaint.setColor(mInitialColor);
mCenterPaint.setStrokeWidth(5);
centerRadius = (r - mPaint.getStrokeWidth() /2) *0.7f;
//边框参数
mLinePaint =newPaint(Paint.ANTI_ALIAS_FLAG);
mLinePaint.setColor(Color.parseColor("#72A1D1"));
mLinePaint.setStrokeWidth(4);
//黑白渐变参数
mRectColors =newint[]{0xFF000000, mCenterPaint.getColor(),0xFFFFFFFF};
mRectPaint =newPaint(Paint.ANTI_ALIAS_FLAG);
mRectPaint.setStrokeWidth(5);
rectLeft = -r - mPaint.getStrokeWidth() *0.5f;
rectTop = r + mPaint.getStrokeWidth() *0.5f +
mLinePaint.getStrokeMiter() *0.5f +15;
rectRight = r + mPaint.getStrokeWidth() *0.5f;
rectBottom = rectTop +50;
}
@Override
protectedvoidonDraw(Canvas canvas) {
//移动中心
canvas.translate(mWidth /2, mHeight /2-50);
//画中心圆
canvas.drawCircle(0,0, centerRadius, mCenterPaint);
//是否显示中心圆外的小圆环
if(highlightCenter || highlightCenterLittle) {
intc = mCenterPaint.getColor();
mCenterPaint.setStyle(Paint.Style.STROKE);
if(highlightCenter) {
mCenterPaint.setAlpha(0xFF);
}elseif(highlightCenterLittle) {
mCenterPaint.setAlpha(0x90);
}
canvas.drawCircle(0,0,
centerRadius + mCenterPaint.getStrokeWidth(), mCenterPaint);
mCenterPaint.setStyle(Paint.Style.FILL);
mCenterPaint.setColor(c);
}
//画色环
canvas.drawOval(newRectF(-r, -r, r, r), mPaint);
//画黑白渐变块
if(downInCircle) {
mRectColors[1] = mCenterPaint.getColor();
}
rectShader =newLinearGradient(rectLeft,0, rectRight,0, mRectColors,null, Shader.TileMode.MIRROR);
mRectPaint.setShader(rectShader);
canvas.drawRect(rectLeft, rectTop, rectRight, rectBottom, mRectPaint);
floatoffset = mLinePaint.getStrokeWidth() /2;
canvas.drawLine(rectLeft - offset, rectTop - offset *2,
rectLeft - offset, rectBottom + offset *2, mLinePaint);//左
canvas.drawLine(rectLeft - offset *2, rectTop - offset,
rectRight + offset *2, rectTop - offset, mLinePaint);//上
canvas.drawLine(rectRight + offset, rectTop - offset *2,
rectRight + offset, rectBottom + offset *2, mLinePaint);//右
canvas.drawLine(rectLeft - offset *2, rectBottom + offset,
rectRight + offset *2, rectBottom + offset, mLinePaint);//下
super.onDraw(canvas);
}
@Override
publicbooleanonTouchEvent(MotionEvent event) {
floatx = event.getX() - mWidth /2;
floaty = event.getY() - mHeight /2+50;
booleaninCircle = inColorCircle(x, y,
r + mPaint.getStrokeWidth() /2, r - mPaint.getStrokeWidth() /2);
booleaninCenter = inCenter(x, y, centerRadius);
booleaninRect = inRect(x, y);
switch(event.getAction()) {
caseMotionEvent.ACTION_DOWN:
downInCircle = inCircle;
downInRect = inRect;
highlightCenter = inCenter;
caseMotionEvent.ACTION_MOVE:
if(downInCircle && inCircle) {//down按在渐变色环内, 且move也在渐变色环内
floatangle = (float) Math.atan2(y, x);
floatunit = (float) (angle / (2* Math.PI));
if(unit <0) {
unit +=1;
}
mCenterPaint.setColor(interpCircleColor(mCircleColors, unit));
if(debug) Log.v(TAG,"色环内, 坐标: "+ x +","+ y);
}elseif(downInRect && inRect) {//down在渐变方块内, 且move也在渐变方块内
mCenterPaint.setColor(interpRectColor(mRectColors, x));
}
if(debug) Log.v(TAG,"[MOVE] 高亮: "+ highlightCenter +"微亮: "+ highlightCenterLittle +" 中心: "+ inCenter);
if((highlightCenter && inCenter) || (highlightCenterLittle && inCenter)) {//点击中心圆, 当前移动在中心圆
highlightCenter =true;
highlightCenterLittle =false;
}elseif(highlightCenter || highlightCenterLittle) {//点击在中心圆, 当前移出中心圆
highlightCenter =false;
highlightCenterLittle =true;
}else{
highlightCenter =false;
highlightCenterLittle =false;
}
invalidate();
break;
caseMotionEvent.ACTION_UP:
if(highlightCenter && inCenter) {//点击在中心圆, 且当前启动在中心圆
if(mListener !=null) {
mListener.colorChanged(mCenterPaint.getColor());
ColorPickerDialog.this.dismiss();
}
}
if(downInCircle) {
downInCircle =false;
}
if(downInRect) {
downInRect =false;
}
if(highlightCenter) {
highlightCenter =false;
}
if(highlightCenterLittle) {
highlightCenterLittle =false;
}
invalidate();
break;
}
returntrue;
}
@Override
protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec) {
super.onMeasure(mWidth, mHeight);
}
/**
* 坐标是否在色环上
* @param x 坐标
* @param y 坐标
* @param outRadius 色环外半径
* @param inRadius 色环内半径
* @return
*/
privatebooleaninColorCircle(floatx,floaty,floatoutRadius,floatinRadius) {
doubleoutCircle = Math.PI * outRadius * outRadius;
doubleinCircle = Math.PI * inRadius * inRadius;
doublefingerCircle = Math.PI * (x * x + y * y);
if(fingerCircle inCircle) {
returntrue;
}else{
returnfalse;
}
}
/**
* 坐标是否在中心圆上
* @param x 坐标
* @param y 坐标
* @param centerRadius 圆半径
* @return
*/
privatebooleaninCenter(floatx,floaty,floatcenterRadius) {
doublecenterCircle = Math.PI * centerRadius * centerRadius;
doublefingerCircle = Math.PI * (x * x + y * y);
if(fingerCircle
returntrue;
}else{
returnfalse;
}
}
/**
* 坐标是否在渐变色中
* @param x
* @param y
* @return
*/
privatebooleaninRect(floatx,floaty) {
if( x <= rectRight && x >=rectLeft && y <= rectBottom && y >=rectTop) {
returntrue;
}else{
returnfalse;
}
}
/**
* 获取圆环上颜色
* @param colors
* @param unit
* @return
*/
privateintinterpCircleColor(intcolors[],floatunit) {
if(unit <=0) {
returncolors[0];
}
if(unit >=1) {
returncolors[colors.length -1];
}
floatp = unit * (colors.length -1);
inti = (int)p;
p -= i;
// now p is just the fractional part [0...1) and i is the index
intc0 = colors[i];
intc1 = colors[i+1];
inta = ave(Color.alpha(c0), Color.alpha(c1), p);
intr = ave(Color.red(c0), Color.red(c1), p);
intg = ave(Color.green(c0), Color.green(c1), p);
intb = ave(Color.blue(c0), Color.blue(c1), p);
returnColor.argb(a, r, g, b);
}
/**
* 获取渐变块上颜色
* @param colors
* @param x
* @return
*/
privateintinterpRectColor(intcolors[],floatx) {
inta, r, g, b, c0, c1;
floatp;
if(x <0) {
c0 = colors[0];
c1 = colors[1];
p = (x + rectRight) / rectRight;
}else{
c0 = colors[1];
c1 = colors[2];
p = x / rectRight;
}
a = ave(Color.alpha(c0), Color.alpha(c1), p);
r = ave(Color.red(c0), Color.red(c1), p);
g = ave(Color.green(c0), Color.green(c1), p);
b = ave(Color.blue(c0), Color.blue(c1), p);
returnColor.argb(a, r, g, b);
}
privateintave(ints,intd,floatp) {
returns + Math.round(p * (d - s));
}
}
/**
* 回调接口
* @author LynK
*
* Create on 2012-1-6 上午8:21:05
*
*/
publicinterfaceOnColorChangedListener {
/**
* 回调函数
* @param color 选中的颜色
*/
voidcolorChanged(intcolor);
}
publicString getTitle() {
returntitle;
}
publicvoidsetTitle(String title) {
this.title = title;
}
publicintgetmInitialColor() {
returnmInitialColor;
}
publicvoidsetmInitialColor(intmInitialColor) {
this.mInitialColor = mInitialColor;
}
publicOnColorChangedListener getmListener() {
returnmListener;
}
publicvoidsetmListener(OnColorChangedListener mListener) {
this.mListener = mListener;
}
}