Android颜色选择器之案例解析

因为画图板中需要使用颜色选择器. 去查了下api demo, 发现有现成的ColorPickerDialog, 但是功能比较简单, 主要是无法选择黑色和白色. 之后也去网上找了下, 倒是发现了几个, 但是用着感觉不太好.就想着自己重写个好了.

先上图
1.测试界面

Android颜色选择器之案例解析

2. 调色板对话框

Android颜色选择器之案例解析

3. 选择颜色

 

Android颜色选择器之案例解析

4.改变字体颜色

Android颜色选择器之案例解析

调色板对话框
  ColorPickerDialog.java

package com.dwood.paintdemo;   

   

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 title 对话框标题  

     * @param listener 回调  

     */  

    public ColorPickerDialog(Context context, String title,    

            OnColorChangedListener listener) {   

        this(context, Color.BLACK, title, listener);   

    }   

        

    /**  

     *   

     * @param context  

     * @param initialColor 初始颜色  

     * @param title 标题  

     * @param listener 回调  

     */  

    public ColorPickerDialog(Context context, int initialColor,    

            String title, OnColorChangedListener listener) {   

        super(context);   

        this.context = context;   

        mListener = listener;   

        mInitialColor = initialColor;   

        this.title = title;   

    }   

   

    @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 色环内半径  

         * <a href='\"http://www.eoeandroid.com/home.php?mod=space&uid=7300\"' target='\"_blank\"'>@return</a>  

         */  

        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 圆半径  

         * <a href='\"http://www.eoeandroid.com/home.php?mod=space&uid=7300\"' target='\"_blank\"'>@return</a>  

         */  

        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  

         * <a href='\"http://www.eoeandroid.com/home.php?mod=space&uid=7300\"' target='\"_blank\"'>@return</a>  

         */  

        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;   

            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="[email protected]">LynK</a>  

     *   

     * Create on 2012-1-6 上午8:21:05  

     *  

     */  

    public interface OnColorChangedListener {   

        /**  

         * 回调函数  

         * @param color 选中的颜色  

         */  

        void colorChanged(int color);   

    }   

        

    public String getTitle() {   

        return title;   

    }   

   

    public void setTitle(String title) {   

        this.title = title;   

    }   

   

    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;   

    }   

}  


下载地址

 

你可能感兴趣的:(选择器)