Android 颜色选择器(ColorPicker)

转自:http://www.iteye.com/topic/1119586

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

 

先上图

1.测试界面 

 

2. 调色板对话框 

 

3. 选择颜色 

 

4.改变字体颜色 
 

 


调色板对话框

ColorPickerDialog.java

 

Java代码    收藏代码
  1. package com.dwood.paintdemo;  
  2.   
  3. import android.app.Dialog;  
  4. import android.content.Context;  
  5. import android.graphics.Canvas;  
  6. import android.graphics.Color;  
  7. import android.graphics.LinearGradient;  
  8. import android.graphics.Paint;  
  9. import android.graphics.RectF;  
  10. import android.graphics.Shader;  
  11. import android.graphics.SweepGradient;  
  12. import android.os.Bundle;  
  13. import android.util.Log;  
  14. import android.view.MotionEvent;  
  15. import android.view.View;  
  16. import android.view.WindowManager;  
  17.   
  18. public class ColorPickerDialog extends Dialog {  
  19.     private final boolean debug = true;  
  20.     private final String TAG = "ColorPicker";  
  21.       
  22.     Context context;  
  23.     private String title;//标题  
  24.     private int mInitialColor;//初始颜色  
  25.     private OnColorChangedListener mListener;  
  26.   
  27.     /** 
  28.      * 初始颜色黑色 
  29.      * @param context 
  30.      * @param title 对话框标题 
  31.      * @param listener 回调 
  32.      */  
  33.     public ColorPickerDialog(Context context, String title,   
  34.             OnColorChangedListener listener) {  
  35.         this(context, Color.BLACK, title, listener);  
  36.     }  
  37.       
  38.     /** 
  39.      *  
  40.      * @param context 
  41.      * @param initialColor 初始颜色 
  42.      * @param title 标题 
  43.      * @param listener 回调 
  44.      */  
  45.     public ColorPickerDialog(Context context, int initialColor,   
  46.             String title, OnColorChangedListener listener) {  
  47.         super(context);  
  48.         this.context = context;  
  49.         mListener = listener;  
  50.         mInitialColor = initialColor;  
  51.         this.title = title;  
  52.     }  
  53.   
  54.     @Override  
  55.     protected void onCreate(Bundle savedInstanceState) {  
  56.         super.onCreate(savedInstanceState);  
  57.         WindowManager manager = getWindow().getWindowManager();  
  58.         int height = (int) (manager.getDefaultDisplay().getHeight() * 0.5f);  
  59.         int width = (int) (manager.getDefaultDisplay().getWidth() * 0.7f);  
  60.         ColorPickerView myView = new ColorPickerView(context, height, width);  
  61.         setContentView(myView);  
  62.         setTitle(title);  
  63.     }  
  64.       
  65.     private class ColorPickerView extends View {  
  66.         private Paint mPaint;//渐变色环画笔  
  67.         private Paint mCenterPaint;//中间圆画笔  
  68.         private Paint mLinePaint;//分隔线画笔  
  69.         private Paint mRectPaint;//渐变方块画笔  
  70.           
  71.         private Shader rectShader;//渐变方块渐变图像  
  72.         private float rectLeft;//渐变方块左x坐标  
  73.         private float rectTop;//渐变方块右x坐标  
  74.         private float rectRight;//渐变方块上y坐标  
  75.         private float rectBottom;//渐变方块下y坐标  
  76.           
  77.         private final int[] mCircleColors;//渐变色环颜色  
  78.         private final int[] mRectColors;//渐变方块颜色  
  79.           
  80.         private int mHeight;//View高  
  81.         private int mWidth;//View宽  
  82.         private float r;//色环半径(paint中部)  
  83.         private float centerRadius;//中心圆半径  
  84.           
  85.         private boolean downInCircle = true;//按在渐变环上  
  86.         private boolean downInRect;//按在渐变方块上  
  87.         private boolean highlightCenter;//高亮  
  88.         private boolean highlightCenterLittle;//微亮  
  89.           
  90.         public ColorPickerView(Context context, int height, int width) {  
  91.             super(context);  
  92.             this.mHeight = height - 36;  
  93.             this.mWidth = width;  
  94.             setMinimumHeight(height - 36);  
  95.             setMinimumWidth(width);  
  96.               
  97.             //渐变色环参数  
  98.             mCircleColors = new int[] {0xFFFF00000xFFFF00FF0xFF0000FF,   
  99.                     0xFF00FFFF0xFF00FF00,0xFFFFFF000xFFFF0000};  
  100.             Shader s = new SweepGradient(00, mCircleColors, null);  
  101.             mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
  102.             mPaint.setShader(s);  
  103.             mPaint.setStyle(Paint.Style.STROKE);  
  104.             mPaint.setStrokeWidth(50);  
  105.             r = width / 2 * 0.7f - mPaint.getStrokeWidth() * 0.5f;  
  106.               
  107.             //中心圆参数  
  108.             mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
  109.             mCenterPaint.setColor(mInitialColor);  
  110.             mCenterPaint.setStrokeWidth(5);  
  111.             centerRadius = (r - mPaint.getStrokeWidth() / 2 ) * 0.7f;  
  112.               
  113.             //边框参数  
  114.             mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
  115.             mLinePaint.setColor(Color.parseColor("#72A1D1"));  
  116.             mLinePaint.setStrokeWidth(4);  
  117.               
  118.             //黑白渐变参数  
  119.             mRectColors = new int[]{0xFF000000, mCenterPaint.getColor(), 0xFFFFFFFF};  
  120.             mRectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
  121.             mRectPaint.setStrokeWidth(5);  
  122.             rectLeft = -r - mPaint.getStrokeWidth() * 0.5f;  
  123.             rectTop = r + mPaint.getStrokeWidth() * 0.5f +   
  124.                     mLinePaint.getStrokeMiter() * 0.5f + 15;  
  125.             rectRight = r + mPaint.getStrokeWidth() * 0.5f;  
  126.             rectBottom = rectTop + 50;  
  127.         }  
  128.   
  129.         @Override  
  130.         protected void onDraw(Canvas canvas) {  
  131.             //移动中心  
  132.             canvas.translate(mWidth / 2, mHeight / 2 - 50);  
  133.             //画中心圆  
  134.             canvas.drawCircle(00, centerRadius,  mCenterPaint);  
  135.             //是否显示中心圆外的小圆环  
  136.             if (highlightCenter || highlightCenterLittle) {  
  137.                 int c = mCenterPaint.getColor();  
  138.                 mCenterPaint.setStyle(Paint.Style.STROKE);  
  139.                 if(highlightCenter) {  
  140.                     mCenterPaint.setAlpha(0xFF);  
  141.                 }else if(highlightCenterLittle) {  
  142.                     mCenterPaint.setAlpha(0x90);  
  143.                 }  
  144.                 canvas.drawCircle(00,   
  145.                         centerRadius + mCenterPaint.getStrokeWidth(),  mCenterPaint);  
  146.                   
  147.                 mCenterPaint.setStyle(Paint.Style.FILL);  
  148.                 mCenterPaint.setColor(c);  
  149.             }  
  150.             //画色环  
  151.             canvas.drawOval(new RectF(-r, -r, r, r), mPaint);  
  152.             //画黑白渐变块  
  153.             if(downInCircle) {  
  154.                 mRectColors[1] = mCenterPaint.getColor();  
  155.             }  
  156.             rectShader = new LinearGradient(rectLeft, 0, rectRight, 0, mRectColors, null, Shader.TileMode.MIRROR);  
  157.             mRectPaint.setShader(rectShader);  
  158.             canvas.drawRect(rectLeft, rectTop, rectRight, rectBottom, mRectPaint);  
  159.             float offset = mLinePaint.getStrokeWidth() / 2;  
  160.             canvas.drawLine(rectLeft - offset, rectTop - offset * 2,   
  161.                     rectLeft - offset, rectBottom + offset * 2, mLinePaint);//左  
  162.             canvas.drawLine(rectLeft - offset * 2, rectTop - offset,   
  163.                     rectRight + offset * 2, rectTop - offset, mLinePaint);//上  
  164.             canvas.drawLine(rectRight + offset, rectTop - offset * 2,   
  165.                     rectRight + offset, rectBottom + offset * 2, mLinePaint);//右  
  166.             canvas.drawLine(rectLeft - offset * 2, rectBottom + offset,   
  167.                     rectRight + offset * 2, rectBottom + offset, mLinePaint);//下  
  168.             super.onDraw(canvas);  
  169.         }  
  170.           
  171.         @Override  
  172.         public boolean onTouchEvent(MotionEvent event) {  
  173.             float x = event.getX() - mWidth / 2;  
  174.             float y = event.getY() - mHeight / 2 + 50;  
  175.             boolean inCircle = inColorCircle(x, y,   
  176.                     r + mPaint.getStrokeWidth() / 2, r - mPaint.getStrokeWidth() / 2);  
  177.             boolean inCenter = inCenter(x, y, centerRadius);  
  178.             boolean inRect = inRect(x, y);  
  179.               
  180.             switch (event.getAction()) {  
  181.                 case MotionEvent.ACTION_DOWN:  
  182.                     downInCircle = inCircle;  
  183.                     downInRect = inRect;  
  184.                     highlightCenter = inCenter;  
  185.                 case MotionEvent.ACTION_MOVE:  
  186.                     if(downInCircle && inCircle) {//down按在渐变色环内, 且move也在渐变色环内  
  187.                         float angle = (float) Math.atan2(y, x);  
  188.                         float unit = (float) (angle / (2 * Math.PI));  
  189.                         if (unit < 0) {  
  190.                             unit += 1;  
  191.                         }  
  192.                         mCenterPaint.setColor(interpCircleColor(mCircleColors, unit));  
  193.                         if(debug) Log.v(TAG, "色环内, 坐标: " + x + "," + y);  
  194.                     }else if(downInRect && inRect) {//down在渐变方块内, 且move也在渐变方块内  
  195.                         mCenterPaint.setColor(interpRectColor(mRectColors, x));  
  196.                     }  
  197.                     if(debug) Log.v(TAG, "[MOVE] 高亮: " + highlightCenter + "微亮: " + highlightCenterLittle + " 中心: " + inCenter);  
  198.                     if((highlightCenter && inCenter) || (highlightCenterLittle && inCenter)) {//点击中心圆, 当前移动在中心圆  
  199.                         highlightCenter = true;  
  200.                         highlightCenterLittle = false;  
  201.                     } else if(highlightCenter || highlightCenterLittle) {//点击在中心圆, 当前移出中心圆  
  202.                         highlightCenter = false;  
  203.                         highlightCenterLittle = true;  
  204.                     } else {  
  205.                         highlightCenter = false;  
  206.                         highlightCenterLittle = false;  
  207.                     }  
  208.                     invalidate();  
  209.                     break;  
  210.                 case MotionEvent.ACTION_UP:  
  211.                     if(highlightCenter && inCenter) {//点击在中心圆, 且当前启动在中心圆  
  212.                         if(mListener != null) {  
  213.                             mListener.colorChanged(mCenterPaint.getColor());  
  214.                             ColorPickerDialog.this.dismiss();  
  215.                         }  
  216.                     }  
  217.                     if(downInCircle) {  
  218.                         downInCircle = false;  
  219.                     }  
  220.                     if(downInRect) {  
  221.                         downInRect = false;  
  222.                     }  
  223.                     if(highlightCenter) {  
  224.                         highlightCenter = false;  
  225.                     }  
  226.                     if(highlightCenterLittle) {  
  227.                         highlightCenterLittle = false;  
  228.                     }  
  229.                     invalidate();  
  230.                     break;  
  231.             }  
  232.             return true;  
  233.         }  
  234.   
  235.         @Override  
  236.         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  237.             super.onMeasure(mWidth, mHeight);  
  238.         }  
  239.   
  240.         /** 
  241.          * 坐标是否在色环上 
  242.          * @param x 坐标 
  243.          * @param y 坐标 
  244.          * @param outRadius 色环外半径 
  245.          * @param inRadius 色环内半径 
  246.          * @return  
  247.          */  
  248.         private boolean inColorCircle(float x, float y, float outRadius, float inRadius) {  
  249.             double outCircle = Math.PI * outRadius * outRadius;  
  250.             double inCircle = Math.PI * inRadius * inRadius;  
  251.             double fingerCircle = Math.PI * (x * x + y * y);  
  252.             if(fingerCircle < outCircle && fingerCircle > inCircle) {  
  253.                 return true;  
  254.             }else {  
  255.                 return false;  
  256.             }  
  257.         }  
  258.           
  259.         /** 
  260.          * 坐标是否在中心圆上 
  261.          * @param x 坐标 
  262.          * @param y 坐标 
  263.          * @param centerRadius 圆半径 
  264.          * @return  
  265.          */  
  266.         private boolean inCenter(float x, float y, float centerRadius) {  
  267.             double centerCircle = Math.PI * centerRadius * centerRadius;  
  268.             double fingerCircle = Math.PI * (x * x + y * y);  
  269.             if(fingerCircle < centerCircle) {  
  270.                 return true;  
  271.             }else {  
  272.                 return false;  
  273.             }  
  274.         }  
  275.           
  276.         /** 
  277.          * 坐标是否在渐变色中 
  278.          * @param x 
  279.          * @param y 
  280.          * @return  
  281.          */  
  282.         private boolean inRect(float x, float y) {  
  283.             if( x <= rectRight && x >=rectLeft && y <= rectBottom && y >=rectTop) {  
  284.                 return true;  
  285.             } else {  
  286.                 return false;  
  287.             }  
  288.         }  
  289.           
  290.         /** 
  291.          * 获取圆环上颜色 
  292.          * @param colors 
  293.          * @param unit 
  294.          * @return  
  295.          */  
  296.         private int interpCircleColor(int colors[], float unit) {  
  297.             if (unit <= 0) {  
  298.                 return colors[0];  
  299.             }  
  300.             if (unit >= 1) {  
  301.                 return colors[colors.length - 1];  
  302.             }  
  303.               
  304.             float p = unit * (colors.length - 1);  
  305.             int i = (int)p;  
  306.             p -= i;  
  307.   
  308.             // now p is just the fractional part [0...1) and i is the index  
  309.             int c0 = colors[i];  
  310.             int c1 = colors[i+1];  
  311.             int a = ave(Color.alpha(c0), Color.alpha(c1), p);  
  312.             int r = ave(Color.red(c0), Color.red(c1), p);  
  313.             int g = ave(Color.green(c0), Color.green(c1), p);  
  314.             int b = ave(Color.blue(c0), Color.blue(c1), p);  
  315.               
  316.             return Color.argb(a, r, g, b);  
  317.         }  
  318.           
  319.         /** 
  320.          * 获取渐变块上颜色 
  321.          * @param colors 
  322.          * @param x 
  323.          * @return  
  324.          */  
  325.         private int interpRectColor(int colors[], float x) {  
  326.             int a, r, g, b, c0, c1;  
  327.             float p;  
  328.             if (x < 0) {  
  329.                 c0 = colors[0];   
  330.                 c1 = colors[1];  
  331.                 p = (x + rectRight) / rectRight;  
  332.             } else {  
  333.                 c0 = colors[1];  
  334.                 c1 = colors[2];  
  335.                 p = x / rectRight;  
  336.             }  
  337.             a = ave(Color.alpha(c0), Color.alpha(c1), p);  
  338.             r = ave(Color.red(c0), Color.red(c1), p);  
  339.             g = ave(Color.green(c0), Color.green(c1), p);  
  340.             b = ave(Color.blue(c0), Color.blue(c1), p);  
  341.             return Color.argb(a, r, g, b);  
  342.         }  
  343.           
  344.         private int ave(int s, int d, float p) {  
  345.             return s + Math.round(p * (d - s));  
  346.         }  
  347.     }  
  348.       
  349.     /** 
  350.      * 回调接口 
  351.      * @author <a href="clarkamx@gmail.com">LynK</a> 
  352.      *  
  353.      * Create on 2012-1-6 上午8:21:05 
  354.      * 
  355.      */  
  356.     public interface OnColorChangedListener {  
  357.         /** 
  358.          * 回调函数 
  359.          * @param color 选中的颜色 
  360.          */  
  361.         void colorChanged(int color);  
  362.     }  
  363.       
  364.     public String getTitle() {  
  365.         return title;  
  366.     }  
  367.   
  368.     public void setTitle(String title) {  
  369.         this.title = title;  
  370.     }  
  371.   
  372.     public int getmInitialColor() {  
  373.         return mInitialColor;  
  374.     }  
  375.   
  376.     public void setmInitialColor(int mInitialColor) {  
  377.         this.mInitialColor = mInitialColor;  
  378.     }  
  379.   
  380.     public OnColorChangedListener getmListener() {  
  381.         return mListener;  
  382.     }  
  383.   
  384.     public void setmListener(OnColorChangedListener mListener) {  
  385.         this.mListener = mListener;  
  386.     }  
  387. }  

 

测试界面 

PaintDemoActivity.java

Java代码    收藏代码
  1. package com.dwood.paintdemo;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.Context;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.widget.Button;  
  8. import android.widget.TextView;  
  9.   
  10. public class PaintDemoActivity extends Activity {  
  11.     Context context;  
  12.     private Button btnColorPicker;  
  13.     private TextView tvText;  
  14.       
  15.     private ColorPickerDialog dialog;  
  16.       
  17.     @Override  
  18.     public void onCreate(Bundle savedInstanceState) {  
  19.         context = this;  
  20.         super.onCreate(savedInstanceState);  
  21.         setContentView(R.layout.main);  
  22.         initViews();  
  23.     }  
  24.     /** 
  25.      * 初始化UI 
  26.      */  
  27.     private void initViews() {  
  28.         btnColorPicker = (Button) findViewById(R.id.btn_color_picker);  
  29.         btnColorPicker.setOnClickListener(new View.OnClickListener() {  
  30.               
  31.             @Override  
  32.             public void onClick(View v) {  
  33.                 dialog = new ColorPickerDialog(context, tvText.getTextColors().getDefaultColor(),   
  34.                         getResources().getString(R.string.btn_color_picker),   
  35.                         new ColorPickerDialog.OnColorChangedListener() {  
  36.                       
  37.                     @Override  
  38.                     public void colorChanged(int color) {  
  39.                         tvText.setTextColor(color);  
  40.                     }  
  41.                 });  
  42.                 dialog.show();  
  43.             }  
  44.         });  
  45.         tvText = (TextView) findViewById(R.id.tv_text);  
  46.     }  
  47. }  

转载于:https://my.oschina.net/aiadaniel/blog/64161

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值