Android 颜色渲染 颜色选择器 ColorPickerDialog剖析

Posted brave-sailor

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 颜色渲染 颜色选择器 ColorPickerDialog剖析相关的知识,希望对你有一定的参考价值。

Android 颜色选择器之ColorPickerDialog剖析

      有这样一个需求,可以让用户自定义背景颜色,这就需要提供一个颜色选择器给用户.

      在android 中,如何实现这样的功能呢,遇到这种需求是,先查看一下ApiDemos,是否已经有相关的实例,果然,找到了一个可以参考的demo:ColorPickerDialog

我已经把apidemos导入到eclipse中,请看截图:

技术分享

 

我们要找的就是这个ColorPickerDialog,在com.example.android.apis.graphics目录下,是一个颜色选择器对话框,在哪个demo中使用的呢,References下之后,发现是在

FingerPaint,也就是涂鸦的例子中:

                                                               技术分享

 

接下来还是直接看代码:

  1. package com.example.android.apis.graphics;  
  2.   
  3. import android.os.Bundle;  
  4. import android.app.Dialog;  
  5. import android.content.Context;  
  6. import android.graphics.*;  
  7. import android.view.MotionEvent;  
  8. import android.view.View;  
  9.   
  10. public class ColorPickerDialog extends Dialog {  
  11.   
  12.     public interface OnColorChangedListener {  
  13.         void colorChanged(int color);  
  14.     }  
  15.   
  16.     private OnColorChangedListener mListener;  
  17.     private int mInitialColor;  
  18.   
  19.     private static class ColorPickerView extends View {//颜色选择器自定义View  
  20.         private Paint mPaint;<span><span></span><span class="comment">//渐变色环画笔</span><span> </span></span>  
  21.         private Paint mCenterPaint;<span><span></span><span class="comment">//中间圆画笔</span><span>  </span></span>  
  22.         private final int[] mColors;<span><span></span><span class="comment">//渐变色环颜色</span><span></span></span>  
  23.         private OnColorChangedListener mListener;//颜色改变回调  
  24.           
  25.         ColorPickerView(Context c, OnColorChangedListener l, int color) {  
  26.             super(c);  
  27.             mListener = l;  
  28.             mColors = new int[] {//渐变色数组  
  29.                 0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00,  
  30.                 0xFFFFFF00, 0xFFFF0000  
  31.             };  
  32.             Shader s = new SweepGradient(0, 0, mColors, null);  
  33.             //初始化渐变色画笔  
  34.             mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
  35.             mPaint.setShader(s);  
  36.             mPaint.setStyle(Paint.Style.STROKE);  
  37.             mPaint.setStrokeWidth(32);  
  38.               
  39.             //初始化中心园画笔  
  40.             mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
  41.             mCenterPaint.setColor(color);  
  42.             mCenterPaint.setStrokeWidth(5);  
  43.         }  
  44.           
  45.         private boolean mTrackingCenter;  
  46.         private boolean mHighlightCenter;  
  47.   
  48.         @Override   
  49.         protected void onDraw(Canvas canvas) {  
  50.             float r = CENTER_X - mPaint.getStrokeWidth()*0.5f;  
  51.               
  52.             //移动中心  
  53.             canvas.translate(CENTER_X, CENTER_X);  
  54.             //画出色环和中心园  
  55.             canvas.drawOval(new RectF(-r, -r, r, r), mPaint);              
  56.             canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);  
  57.               
  58.             if (mTrackingCenter) {  
  59.                 int c = mCenterPaint.getColor();  
  60.                 mCenterPaint.setStyle(Paint.Style.STROKE);  
  61.                   
  62.                 if (mHighlightCenter) {  
  63.                     mCenterPaint.setAlpha(0xFF);  
  64.                 } else {  
  65.                     mCenterPaint.setAlpha(0x80);  
  66.                 }  
  67.                 canvas.drawCircle(0, 0,  
  68.                                   CENTER_RADIUS + mCenterPaint.getStrokeWidth(),  
  69.                                   mCenterPaint);  
  70.                   
  71.                 mCenterPaint.setStyle(Paint.Style.FILL);  
  72.                 mCenterPaint.setColor(c);  
  73.             }  
  74.         }  
  75.           
  76.         @Override  
  77.         protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  78.             setMeasuredDimension(CENTER_X*2, CENTER_Y*2);  
  79.         }  
  80.           
  81.         private static final int CENTER_X = 100;  
  82.         private static final int CENTER_Y = 100;  
  83.         private static final int CENTER_RADIUS = 32;  
  84.   
  85.         private int floatToByte(float x) {  
  86.             int n = java.lang.Math.round(x);  
  87.             return n;  
  88.         }  
  89.         private int pinToByte(int n) {  
  90.             if (n < 0) {  
  91.                 n = 0;  
  92.             } else if (n > 255) {  
  93.                 n = 255;  
  94.             }  
  95.             return n;  
  96.         }  
  97.           
  98.         private int ave(int s, int d, float p) {  
  99.             return s + java.lang.Math.round(p * (d - s));  
  100.         }  
  101.           
  102.         private int interpColor(int colors[], float unit) {  
  103.             if (unit <= 0) {  
  104.                 return colors[0];  
  105.             }  
  106.             if (unit >= 1) {  
  107.                 return colors[colors.length - 1];  
  108.             }  
  109.               
  110.             float p = unit * (colors.length - 1);  
  111.             int i = (int)p;  
  112.             p -= i;  
  113.   
  114.             // now p is just the fractional part [0...1) and i is the index  
  115.             int c0 = colors[i];  
  116.             int c1 = colors[i+1];  
  117.             int a = ave(Color.alpha(c0), Color.alpha(c1), p);  
  118.             int r = ave(Color.red(c0), Color.red(c1), p);  
  119.             int g = ave(Color.green(c0), Color.green(c1), p);  
  120.             int b = ave(Color.blue(c0), Color.blue(c1), p);  
  121.               
  122.             return Color.argb(a, r, g, b);  
  123.         }  
  124.           
  125.         private int rotateColor(int color, float rad) {  
  126.             float deg = rad * 180 / 3.1415927f;  
  127.             int r = Color.red(color);  
  128.             int g = Color.green(color);  
  129.             int b = Color.blue(color);  
  130.               
  131.             ColorMatrix cm = new ColorMatrix();  
  132.             ColorMatrix tmp = new ColorMatrix();  
  133.   
  134.             cm.setRGB2YUV();  
  135.             tmp.setRotate(0, deg);  
  136.             cm.postConcat(tmp);  
  137.             tmp.setYUV2RGB();  
  138.             cm.postConcat(tmp);  
  139.               
  140.             final float[] a = cm.getArray();  
  141.   
  142.             int ir = floatToByte(a[0] * r +  a[1] * g +  a[2] * b);  
  143.             int ig = floatToByte(a[5] * r +  a[6] * g +  a[7] * b);  
  144.             int ib = floatToByte(a[10] * r + a[11] * g + a[12] * b);  
  145.               
  146.             return Color.argb(Color.alpha(color), pinToByte(ir),  
  147.                               pinToByte(ig), pinToByte(ib));  
  148.         }  
  149.           
  150.         private static final float PI = 3.1415926f;  
  151.   
  152.         @Override  
  153.         public boolean onTouchEvent(MotionEvent event) {  
  154.             float x = event.getX() - CENTER_X;  
  155.             float y = event.getY() - CENTER_Y;  
  156.             boolean inCenter = java.lang.Math.sqrt(x*x + y*y) <= CENTER_RADIUS;  
  157.               
  158.             switch (event.getAction()) {  
  159.                 case MotionEvent.ACTION_DOWN:  
  160.                     mTrackingCenter = inCenter;  
  161.                     if (inCenter) {//是否则中心园  
  162.                         mHighlightCenter = true;  
  163.                         invalidate();  
  164.                         break;  
  165.                     }  
  166.                 case MotionEvent.ACTION_MOVE:  
  167.                     if (mTrackingCenter) {  
  168.                         if (mHighlightCenter != inCenter) {  
  169.                             mHighlightCenter = inCenter;  
  170.                             invalidate();  
  171.                         }  
  172.                     } else {  
  173.                         float angle = (float)java.lang.Math.atan2(y, x);  
  174.                         // need to turn angle [-PI ... PI] into unit [0....1]  
  175.                         float unit = angle/(2*PI);  
  176.                         if (unit < 0) {  
  177.                             unit += 1;  
  178.                         }  
  179.                         mCenterPaint.setColor(interpColor(mColors, unit));  
  180.                         invalidate();  
  181.                     }  
  182.                     break;  
  183.                 case MotionEvent.ACTION_UP:  
  184.                     if (mTrackingCenter) {  
  185.                         if (inCenter) {  
  186.                             mListener.colorChanged(mCenterPaint.getColor());  
  187.                         }  
  188.                         mTrackingCenter = false;    // so we draw w/o halo  
  189.                         invalidate();  
  190.                     }  
  191.                     break;  
  192.             }  
  193.             return true;  
  194.         }  
  195.     }  
  196.   
  197.     public ColorPickerDialog(Context context,  
  198.                              OnColorChangedListener listener,  
  199.                              int initialColor) {  
  200.         super(context);  
  201.           
  202.         mListener = listener;  
  203.         mInitialColor = initialColor;  
  204.     }  
  205.   
  206.     @Override  
  207.     protected void onCreate(Bundle savedInstanceState) {  
  208.         super.onCreate(savedInstanceState);  
  209.         OnColorChangedListener l = new OnColorChangedListener() {  
  210.             public void colorChanged(int color) {  
  211.                 mListener.colorChanged(color);  
  212.                 dismiss();  
  213.             }  
  214.         };  
  215.   
  216.         setContentView(new ColorPickerView(getContext(), l, mInitialColor));  
  217.         setTitle("Pick a Color");  
  218.     }  
  219. }  

        当然,目前的这个例子还有一定的局限,比如无黑白色,只能选择大概的颜色区间(后续会讲解). 当然只要把这个demo研究好后,具体的改进不是问题.

 

另附上ApiDemos下载地址: http://download.csdn.net/detail/t12x3456/6007883

如有转载,请声明出处: 时之沙: http://blog.csdn.net/t12x3456

以上是关于Android 颜色渲染 颜色选择器 ColorPickerDialog剖析的主要内容,如果未能解决你的问题,请参考以下文章

Android 颜色渲染 ComposeShader组合渲染

Android 颜色渲染 BitmapShader位图渲染

使用android中的颜色选择器更改textview的文本颜色和背景颜色

如何在 xamarin.UWP 中的 Viewcell 项目选择上设置自己的颜色?

Android选择器长按颜色

在android中使用的颜色选择器