Andriod中的两种自定义颜色选择器

第一种:
import android.app.Dialog;  
import android.content.Context;  
import android.graphics.Canvas;  
import android.graphics.Color;  
import android.graphics.LinearGradient;  
import android.graphics.Paint;  
import android.graphics.RectF;  
import android.graphics.Shader;  
import android.graphics.SweepGradient;  
import android.os.Bundle;  
import android.view.MotionEvent;  
import android.view.View;  
  
public class ColorPickerDialog extends Dialog {  
  
    public interface OnColorChangedListener {  
        void colorChanged(int color);  
    }  
  
    private OnColorChangedListener mListener;  
    private int mInitialColor;  
  
    private static class ColorPickerView extends View {  
        private Paint mPaint;  
        private Paint mCenterPaint;  
        private Paint mRadialPaint;  
        private final int[] mRadialColors;  
        private OnColorChangedListener mListener;  
  
        private Paint mGradientPaint;  
        private int[] mLinearColors;  
      
        ColorPickerView(Context c, OnColorChangedListener l, int color) {  
            super(c);  
            mListener = l;  
            mRadialColors = new int[] { 0xFFFF0000, 0xFFFF00FF, 0xFF0000FF,  
                    0xFF00FFFF, 0xFF00FF00, 0xFFFFFF00, 0xFFFF0000 };  
            Shader s = new SweepGradient(0, 0, mRadialColors, null);  
  
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
            mPaint.setShader(s);  
            mPaint.setStyle(Paint.Style.STROKE);  
            mPaint.setStrokeWidth(32);  
  
            mLinearColors = getColors(color);  
            Shader shader = new LinearGradient(0, 0, Center_X * 2, 0,  
                    mLinearColors, null, Shader.TileMode.CLAMP);  
  
            mGradientPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
            mGradientPaint.setStyle(Paint.Style.STROKE);  
            mGradientPaint.setShader(shader);  
            mGradientPaint.setStrokeWidth(32);  
  
            mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
            mCenterPaint.setColor(color);  
            mCenterPaint.setStrokeWidth(6);  
  
            mRadialPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
            mRadialPaint.setColor(color);  
            mRadialPaint.setStrokeWidth(6);  
        }  
  
        private int[] getColors(int color) {  
            if (color == Color.BLACK || color == Color.WHITE) {  
                return new int[] { Color.BLACK, Color.WHITE };  
            }  
            return new int[] { Color.BLACK, color, Color.WHITE };  
        }  
  
        private boolean mTrackingCenter;  
        private boolean mHighlightCenter;  
        private boolean mTrackingLinGradient;  
  
        @Override  
        protected void onDraw(Canvas canvas) {  
            float r = COLOR_CIRCLE - mPaint.getStrokeWidth() * 0.5f;  
  
            canvas.translate(Center_X, COLOR_CIRCLE);  
              
            canvas.drawOval(new RectF(-r, -r, r, r), mPaint);  
            canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);  
  
            if (mTrackingCenter) {  
                int color = mCenterPaint.getColor();  
                mCenterPaint.setStyle(Paint.Style.STROKE);  
  
                if (mHighlightCenter) {  
                    mCenterPaint.setAlpha(0xFF);  
                } else {  
                    mCenterPaint.setAlpha(0x80);  
                }  
                canvas.drawCircle(0, 0, CENTER_RADIUS  
                        + mCenterPaint.getStrokeWidth(), mCenterPaint);  
  
                mCenterPaint.setStyle(Paint.Style.FILL);  
                mCenterPaint.setColor(color);  
            }  
  
            int color = mRadialPaint.getColor();  
            mLinearColors = getColors(color);  
            Shader shader = new LinearGradient(0, 0, Center_X * 2, 0,  
                    mLinearColors, null, Shader.TileMode.CLAMP);  
            mGradientPaint.setShader(shader);  
  
            canvas.translate(-Center_X, 0);  
            canvas.drawLine(0, r + 50, Center_X * 2, r + 50, mGradientPaint);  
        }  
  
        @Override  
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {   
            /*super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
            int parentWidth = MeasureSpec.getSize(widthMeasureSpec); 
            int parentHeight = MeasureSpec.getSize(heightMeasureSpec); 
            setMeasuredDimension(parentWidth, parentHeight); 
            Center_X = (int) Math.ceil(parentWidth*.5); 
            Center_Y = (int) Math.ceil(parentHeight*.5);*/  
              
            setMeasuredDimension(Center_X * 2, Center_Y * 2 + 70);  
        }  
  
        private static int Center_X = 110;  
        private static int Center_Y = 100;  
        private static final int CENTER_RADIUS = 32;  
        private static final int COLOR_CIRCLE = 100;  
  
        private int ave(int s, int d, float p) {  
            return s + java.lang.Math.round(p * (d - s));  
        }  
  
        private int interpColor(int colors[], float unit) {  
            if (unit <= 0) {  
                return colors[0];  
            }  
            if (unit >= 1) {  
                return colors[colors.length - 1];  
            }  
  
            float p = unit * (colors.length - 1);  
            int i = (int) p;  
            p -= i;  
  
            // now p is just the fractional part [0...1) and i is the index  
            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);  
        }  
  
        private static final float PI = 3.1415926f;  
  
        @Override  
        public boolean onTouchEvent(MotionEvent event) {  
            float x = event.getX() - Center_X;  
            float y = event.getY() - COLOR_CIRCLE;  
            boolean inCenter = Math.sqrt(x * x + y * y) <= CENTER_RADIUS;  
            boolean outOfRadialGradient = y > COLOR_CIRCLE;  
  
            switch (event.getAction()) {  
            case MotionEvent.ACTION_DOWN:  
                mTrackingCenter = inCenter;  
                mTrackingLinGradient = outOfRadialGradient;  
                if (inCenter) {  
                    mHighlightCenter = true;  
                    invalidate();  
                    break;  
                }  
            case MotionEvent.ACTION_MOVE:  
                if (mTrackingCenter) {  
                    if (mHighlightCenter != inCenter) {  
                        mHighlightCenter = inCenter;  
                        invalidate();  
                    }  
                } else if (mTrackingLinGradient) {  
                    float unit = Math.max(0, Math.min(Center_X * 2, x  
                            + Center_X))  
                            / (Center_X * 2);  
                    mCenterPaint.setColor(interpColor(mLinearColors, unit));  
                    invalidate();  
                } else {  
                    float angle = (float) Math.atan2(y, x);  
                    // need to turn angle [-PI ... PI] into unit [0....1]  
                    float unit = angle / (2 * PI);  
                    if (unit < 0) {  
                        unit += 1;  
                    }  
                    int color = interpColor(mRadialColors, unit);  
                    mCenterPaint.setColor(color);  
                    mRadialPaint.setColor(color);  
                    invalidate();  
                }  
                break;  
            case MotionEvent.ACTION_UP:  
                if (mTrackingCenter) {  
                    if (inCenter) {  
                        mListener.colorChanged(mCenterPaint.getColor());  
                    }  
                    mTrackingCenter = false; // so we draw w/o halo  
                    invalidate();  
                }  
                break;  
            }  
            return true;  
        }  
    }  
  
    public ColorPickerDialog(Context context, OnColorChangedListener listener,  
            int initialColor) {  
        super(context);  
  
        mListener = listener;  
        mInitialColor = initialColor;  
    }  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        OnColorChangedListener l = new OnColorChangedListener() {  
            public void colorChanged(int color) {  
                mListener.colorChanged(color);  
                dismiss();  
            }  
        };    
          
  
        this.setContentView(new ColorPickerView(this.getContext(), l, mInitialColor));  
        this.setTitle(R.string.color_pick);   
          
        /*Display display = this.getWindow().getWindowManager().getDefaultDisplay(); 
        if(display.getWidth() < display.getHeight()) { 
            this.getWindow().setLayout( 
                    LayoutParams.FILL_PARENT,  
                    (int) Math.ceil(display.getHeight()*.7f) 
            ); 
        } 
        else { 
            this.getWindow().setLayout(                  
                    (int) Math.ceil(display.getWidth()*.7f), 
                    LayoutParams.FILL_PARENT 
            ); 
        }*/  
    }  
}  
new ColorPickerDialog(  
                context,   
                new ColorPickerDialog.OnColorChangedListener() {                      
                    public void colorChanged(int color) {  
                        XXX.setColor(color);  
                    }  
                },   
                oldColor  
        ).show();  

第二种:

package com.example.draw;

import android.app.AlertDialog;//透明
import android.app.Dialog;  
import android.content.Context;  
import android.graphics.Canvas;  
import android.graphics.Color;  
import android.graphics.LinearGradient;  
import android.graphics.Paint;  
import android.graphics.RectF;  
import android.graphics.Shader;  
import android.graphics.SweepGradient;  
import android.os.Bundle;  
import android.util.Log;  
import android.view.MotionEvent;  
import android.view.View;  
import android.view.WindowManager;  
  
public class ColorPickerDialog extends Dialog {  
    private final boolean debug = true;  
    private final String TAG = "ColorPicker";  
      
    
    Context context;  
    private String title = "颜色选择器";//标题  
    private int mInitialColor;//初始颜色  
    private OnColorChangedListener mListener;  
  
    /** 
     * 初始颜色黑色 
     * @param context 
     * @param listener 回调 
     */  
    public ColorPickerDialog(Context context, String title,   
            OnColorChangedListener listener) {  
        this(context, Color.BLACK, listener);  
    }  
      
    /** 
     *  
     * @param context 
     * @param initialColor 初始颜色 
     * @param listener 回调 
     */  
    public ColorPickerDialog(Context context, int initialColor,   
           OnColorChangedListener listener) {  
        super(context);  
        this.context = context;  
        mListener = listener;  
        mInitialColor = initialColor;  
    }
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        WindowManager manager = getWindow().getWindowManager();  
        int height = (int) (manager.getDefaultDisplay().getHeight() * 0.5f);  
        int width = (int) (manager.getDefaultDisplay().getWidth() * 0.7f);  
        ColorPickerView myView = new ColorPickerView(context, height, width);  
        setContentView(myView);  
        setTitle(title);  
    }  
      
    private class ColorPickerView extends View {  
        private Paint mPaint;//渐变色环画笔  
        private Paint mCenterPaint;//中间圆画笔  
        private Paint mLinePaint;//分隔线画笔  
        private Paint mRectPaint;//渐变方块画笔  
          
        private Shader rectShader;//渐变方块渐变图像  
        private float rectLeft;//渐变方块左x坐标  
        private float rectTop;//渐变方块右x坐标  
        private float rectRight;//渐变方块上y坐标  
        private float rectBottom;//渐变方块下y坐标  
          
        private final int[] mCircleColors;//渐变色环颜色  
        private final int[] mRectColors;//渐变方块颜色  
          
        private int mHeight;//View高  
        private int mWidth;//View宽  
        private float r;//色环半径(paint中部)  
        private float centerRadius;//中心圆半径  
          
        private boolean downInCircle = true;//按在渐变环上  
        private boolean downInRect;//按在渐变方块上  
        private boolean highlightCenter;//高亮  
        private boolean highlightCenterLittle;//微亮  
          
        public ColorPickerView(Context context, int height, int width) {  
            super(context);  
            this.mHeight = height - 36;  
            this.mWidth = width;  
            setMinimumHeight(height - 36);  
            setMinimumWidth(width);  
              
            //渐变色环参数  
            mCircleColors = new int[] {0xFFFF0000, 0xFFFF00FF, 0xFF0000FF,   
                    0xFF00FFFF, 0xFF00FF00,0xFFFFFF00, 0xFFFF0000};  
            Shader s = new SweepGradient(0, 0, mCircleColors, null);  
            mPaint = new Paint(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 = new Paint(Paint.ANTI_ALIAS_FLAG);  
            mCenterPaint.setColor(mInitialColor);  
            mCenterPaint.setStrokeWidth(5);  
            centerRadius = (r - mPaint.getStrokeWidth() / 2 ) * 0.7f;  
              
            //边框参数  
            mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
            mLinePaint.setColor(Color.parseColor("#72A1D1"));  
            mLinePaint.setStrokeWidth(4);  
              
            //黑白渐变参数  
            mRectColors = new int[]{0xFF000000, mCenterPaint.getColor(), 0xFFFFFFFF};  
            mRectPaint = new Paint(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  
        protected void onDraw(Canvas canvas) {  
            //移动中心  
            canvas.translate(mWidth / 2, mHeight / 2 - 50);  
            //画中心圆  
            canvas.drawCircle(0, 0, centerRadius,  mCenterPaint);  
            //是否显示中心圆外的小圆环  
            if (highlightCenter || highlightCenterLittle) {  
                int c = mCenterPaint.getColor();  
                mCenterPaint.setStyle(Paint.Style.STROKE);  
                if(highlightCenter) {  
                    mCenterPaint.setAlpha(0xFF);  
                }else if(highlightCenterLittle) {  
                    mCenterPaint.setAlpha(0x90);  
                }  
                canvas.drawCircle(0, 0,   
                        centerRadius + mCenterPaint.getStrokeWidth(),  mCenterPaint);  
                  
                mCenterPaint.setStyle(Paint.Style.FILL);  
                mCenterPaint.setColor(c);  
            }  
            //画色环  
            canvas.drawOval(new RectF(-r, -r, r, r), mPaint);  
            //画黑白渐变块  
            if(downInCircle) {  
                mRectColors[1] = mCenterPaint.getColor();  
            }  
            rectShader = new LinearGradient(rectLeft, 0, rectRight, 0, mRectColors, null, Shader.TileMode.MIRROR);  
            mRectPaint.setShader(rectShader);  
            canvas.drawRect(rectLeft, rectTop, rectRight, rectBottom, mRectPaint);  
            float offset = 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  
        public boolean onTouchEvent(MotionEvent event) {  
            float x = event.getX() - mWidth / 2;  
            float y = event.getY() - mHeight / 2 + 50;  
            boolean inCircle = inColorCircle(x, y,   
                    r + mPaint.getStrokeWidth() / 2, r - mPaint.getStrokeWidth() / 2);  
            boolean inCenter = inCenter(x, y, centerRadius);  
            boolean inRect = inRect(x, y);  
              
            switch (event.getAction()) {  
                case MotionEvent.ACTION_DOWN:  
                    downInCircle = inCircle;  
                    downInRect = inRect;  
                    highlightCenter = inCenter;  
                case MotionEvent.ACTION_MOVE:  
                    if(downInCircle && inCircle) {//down按在渐变色环内, 且move也在渐变色环内  
                        float angle = (float) Math.atan2(y, x);  
                        float unit = (float) (angle / (2 * Math.PI));  
                        if (unit < 0) {  
                            unit += 1;  
                        }  
                        mCenterPaint.setColor(interpCircleColor(mCircleColors, unit));  
                        if(debug) Log.v(TAG, "色环内, 坐标: " + x + "," + y);  
                    }else if(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;  
                    } else if(highlightCenter || highlightCenterLittle) {//点击在中心圆, 当前移出中心圆  
                        highlightCenter = false;  
                        highlightCenterLittle = true;  
                    } else {  
                        highlightCenter = false;  
                        highlightCenterLittle = false;  
                    }  
                    invalidate();  
                    break;  
                case MotionEvent.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;  
            }  
            return true;  
        }  
  
        @Override  
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
            super.onMeasure(mWidth, mHeight);  
        }  
  
        /** 
         * 坐标是否在色环上 
         * @param x 坐标 
         * @param y 坐标 
         * @param outRadius 色环外半径 
         * @param inRadius 色环内半径 
         * @return 
         */  
        private boolean inColorCircle(float x, float y, float outRadius, float inRadius) {  
            double outCircle = Math.PI * outRadius * outRadius;  
            double inCircle = Math.PI * inRadius * inRadius;  
            double fingerCircle = Math.PI * (x * x + y * y);  
            if(fingerCircle < outCircle && fingerCircle > inCircle) {  
                return true;  
            }else {  
                return false;  
            }  
        }  
          
        /** 
         * 坐标是否在中心圆上 
         * @param x 坐标 
         * @param y 坐标 
         * @param centerRadius 圆半径 
         * @return 
         */  
        private boolean inCenter(float x, float y, float centerRadius) {  
            double centerCircle = Math.PI * centerRadius * centerRadius;  
            double fingerCircle = Math.PI * (x * x + y * y);  
            if(fingerCircle < centerCircle) {  
                return true;  
            }else {  
                return false;  
            }  
        }  
          
        /** 
         * 坐标是否在渐变色中 
         * @param x 
         * @param y 
         * @return 
         */  
        private boolean inRect(float x, float y) {  
            if( x <= rectRight && x >=rectLeft && y <= rectBottom && y >=rectTop) {  
                return true;  
            } else {  
                return false;  
            }  
        }  
          
        /** 
         * 获取圆环上颜色 
         * @param colors 
         * @param unit 
         * @return 
         */  
        private int interpCircleColor(int colors[], float unit) {  
            if (unit <= 0) {  
                return colors[0];  
            }  
            if (unit >= 1) {  
                return colors[colors.length - 1];  
            }  
              
            float p = unit * (colors.length - 1);  
            int i = (int)p;  
            p -= i;  
  
            // now p is just the fractional part [0...1) and i is the index  
            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);  
        }  
          
        /** 
         * 获取渐变块上颜色 
         * @param colors 
         * @param x 
         * @return 
         */  
        private int interpRectColor(int colors[], float x) {  
            int a, r, g, b, c0, c1;  
            float p;  
            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);  
            return Color.argb(a, r, g, b);  
        }  
          
        private int ave(int s, int d, float p) {  
            return s + Math.round(p * (d - s));  
        }  
    }  
      
    /** 
     * 回调接口 
     * @author <a href="clarkamx@gmail.com">LynK</a> 
     *  
     * Create on 2012-1-6 上午8:21:05 
     * 
     */  
    public interface OnColorChangedListener {  
        /** 
         * 回调函数 
         * @param color 选中的颜色 
         */  
        void colorChanged(int color);  
    }  
 
    public int getmInitialColor() {  
        return mInitialColor;  
    }  
  
    public void setmInitialColor(int mInitialColor) {  
        this.mInitialColor = mInitialColor;  
    }  
  
    public OnColorChangedListener getmListener() {  
        return mListener;  
    }  
  
    public void setmListener(OnColorChangedListener mListener) {  
        this.mListener = mListener;  
    }  
}  

dialog = new ColorPickerDialog(this, p.getColor(),
					new ColorPickerDialog.OnColorChangedListener() {
						@Override
						public void colorChanged(int color) {
							p.setColor(color);
						}
					});
			dialog.show();


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值