zoukankan      html  css  js  c++  java
  • Android颜色选择器之案例解析

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

    先上图
    1.测试界面

    2. 调色板对话框

    3. 选择颜色

    4.改变字体颜色

    调色板对话框
      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="clarkamx@gmail.com">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;   
        }   
    }  


    下载地址

  • 相关阅读:
    sql
    字符和字符串处理例子
    如何用火狐设置代理
    数组指针的一个小例子
    (转)数组指针和指针数组的区别
    函数
    (转)C语言指针5分钟教程
    通俗版解释网关,IP地址,ARP欺骗,DDOS攻击
    计算网络地址
    计算机网络性能指标
  • 原文地址:https://www.cnblogs.com/vus520/p/2561949.html
Copyright © 2011-2022 走看看