歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android 顏色選擇器(ColorPicker)

因為畫圖板中需要使用顏色選擇器. 去查了下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="[email protected]">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. }  
Copyright © Linux教程網 All Rights Reserved