Search This Blog

Tuesday 21 February 2012

Custom Color picker dialog in android

Here i wrote a code with help of AndroidDeveloper'sBestGuide. It is just concept of implement canvas with a dialog box.
We create different color by using Canvas. and then we select different color with the help of canvas.
With the help of this example ,you will also read how to create a custom diaolog

For more information about canvas you. Game Development using Surface View Part III , Game Development Using Canvas Part I

Lets do it step by step


1) Create One XML file in res/layout/main.xml


<?xml version="1.0" encoding="UTF-8"?>  
   <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   android:layout_width="match_parent"  
   android:layout_height="wrap_content"  
   android:padding="20dip" android:id="@+id/main"  
   android:orientation="vertical">  
   <Button android:layout_width="wrap_content"     android:layout_height="wrap_content"  
     android:layout_gravity="center" android:text="Change Background"  
     android:id="@+id/change_color"/>  
 </LinearLayout>  

2) Create One activity and register in manifest file  

Never forget to register your activity into manifest. This activity has only one button. If you click button then it will pop up color picker. Then you can select any color by just touching it


public class ColorPicker extends Activity{  
   private LinearLayout ll;  
   @Override  
   protected void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.main);  
     Button btn=(Button) findViewById(R.id.change_color);  
     ll=(LinearLayout) findViewById(R.id.main);  
     btn.setOnClickListener(new OnClickListener() {  
       @Override  
       public void onClick(View v) {  
         ColorPickerDialog cpd=new ColorPickerDialog(ColorPicker.this, listener, 0);  
         cpd.show();  
       }  
     });  
    }  
    @Override  
   protected void onResume() {  
     super.onResume();  
     ll.setBackgroundColor(ColorAh);  
   }  
   OnColorChangedListener listener=new OnColorChangedListener() {  
       @Override  
       public void colorChanged(int color) {  
         Toast.makeText(ColorPicker.this, ""+color, Toast.LENGTH_LONG).show();  
         ColorAh=color;  
         ll.setBackgroundColor(ColorAh);  
       }  
     };  
   private int ColorAh=Color.BLACK;  
 }  

3)Now create a custom dialog

This is the main task. Here with the help of a canvas we will create surface with different color. If you touch any coordinate then it will give respective point color code. This all is a part of a custom dialog. When user touch any point we will select a color and dismiss dialog box.


public class ColorPickerDialog extends Dialog {  
   public interface OnColorChangedListener {  
     void colorChanged(int color);  
   }  
   private OnColorChangedListener mListener;  
   private int mInitialColor;  
   private static class ColorPickerView extends View {  
     private Paint mPaint;  
     private Paint mCenterPaint;  
     private final int[] mColors;  
     private OnColorChangedListener mListener;  
     ColorPickerView(Context c, OnColorChangedListener l, int color) {  
       super(c);  
       mListener = l;  
       mColors = new int[] {  
         0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00,  
         0xFFFFFF00, 0xFFFF0000  
       };  
       Shader s = new SweepGradient(0, 0, mColors, null);  
       mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
       mPaint.setShader(s);  
       mPaint.setStyle(Paint.Style.STROKE);  
       mPaint.setStrokeWidth(32);  
       mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
       mCenterPaint.setColor(color);  
       mCenterPaint.setStrokeWidth(5);  
     }  
     private boolean mTrackingCenter;  
     private boolean mHighlightCenter;  
     @Override  
     protected void onDraw(Canvas canvas) {  
       float r = CENTER_X - mPaint.getStrokeWidth()*0.5f;  
       canvas.translate(CENTER_X, CENTER_X);  
       canvas.drawOval(new RectF(-r, -r, r, r), mPaint);  
       canvas.drawCircle(0, 0, CENTER_RADIUS, mCenterPaint);  
       if (mTrackingCenter) {  
         int c = mCenterPaint.getColor();  
         mCenterPaint.setStyle(Paint.Style.STROKE);  
         if (mHighlightCenter) {  
           mCenterPaint.setAlpha(0xFF);  
         } else {  
           mCenterPaint.setAlpha(0x80);  
         }  
         canvas.drawCircle(0, 0,  
                  CENTER_RADIUS + mCenterPaint.getStrokeWidth(),  
                  mCenterPaint);  
         mCenterPaint.setStyle(Paint.Style.FILL);  
         mCenterPaint.setColor(c);  
       }  
     }  
     @Override  
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
       setMeasuredDimension(CENTER_X*2, CENTER_Y*2);  
     }  
     private static final int CENTER_X = 100;  
     private static final int CENTER_Y = 100;  
     private static final int CENTER_RADIUS = 32;  
     private int floatToByte(float x) {  
       int n = java.lang.Math.round(x);  
       return n;  
     }  
     private int pinToByte(int n) {  
       if (n < 0) {  
         n = 0;  
       } else if (n > 255) {  
         n = 255;  
       }  
       return n;  
     }  
     private int ave(int s, int d, float p) {  
       return s + java.lang.Math.round(p * (d - s));  
     }  
     private int interpColor(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[i];  
       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);  
     }  
     private int rotateColor(int color, float rad) {  
       float deg = rad * 180 / 3.1415927f;  
       int r = Color.red(color);  
       int g = Color.green(color);  
       int b = Color.blue(color);  
       ColorMatrix cm = new ColorMatrix();  
       ColorMatrix tmp = new ColorMatrix();  
       cm.setRGB2YUV();  
       tmp.setRotate(0, deg);  
       cm.postConcat(tmp);  
       tmp.setYUV2RGB();  
       cm.postConcat(tmp);  
       final float[] a = cm.getArray();  
       int ir = floatToByte(a[0] * r + a[1] * g + a[2] * b);  
       int ig = floatToByte(a[5] * r + a[6] * g + a[7] * b);  
       int ib = floatToByte(a[10] * r + a[11] * g + a[12] * b);  
       return Color.argb(Color.alpha(color), pinToByte(ir),  
                pinToByte(ig), pinToByte(ib));  
     }  
     private static final float PI = 3.1415926f;  
     @Override  
     public boolean onTouchEvent(MotionEvent event) {  
       float x = event.getX() - CENTER_X;  
       float y = event.getY() - CENTER_Y;  
       boolean inCenter = java.lang.Math.sqrt(x*x + y*y) <= CENTER_RADIUS;  
       switch (event.getAction()) {  
         case MotionEvent.ACTION_DOWN:  
           mTrackingCenter = inCenter;  
           if (inCenter) {  
             mHighlightCenter = true;  
             invalidate();  
             break;  
           }  
         case MotionEvent.ACTION_MOVE:  
           if (mTrackingCenter) {  
             if (mHighlightCenter != inCenter) {  
               mHighlightCenter = inCenter;  
               invalidate();  
             }  
           } else {  
             float angle = (float)java.lang.Math.atan2(y, x);  
             // need to turn angle [-PI ... PI] into unit [0....1]  
             float unit = angle/(2*PI);  
             if (unit < 0) {  
               unit += 1;  
             }  
             mCenterPaint.setColor(interpColor(mColors, unit));  
             invalidate();  
           }  
           break;  
         case MotionEvent.ACTION_UP:  
           if (mTrackingCenter) {  
             if (inCenter) {  
               mListener.colorChanged(mCenterPaint.getColor());  
             }  
             mTrackingCenter = false;  // so we draw w/o halo  
             invalidate();  
           }  
           break;  
       }  
       return true;  
     }  
   }  
   public ColorPickerDialog(Context context,  
                OnColorChangedListener listener,  
                int initialColor) {  
     super(context);  
     mListener = listener;  
     mInitialColor = initialColor;  
   }  
   @Override  
   protected void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     OnColorChangedListener l = new OnColorChangedListener() {  
       public void colorChanged(int color) {  
         mListener.colorChanged(color);  
         dismiss();  
       }  
     };  
     setContentView(new ColorPickerView(getContext(), l, mInitialColor));  
     setTitle("Pick a Color");  
   }  
 }  

 Now screen shot will show our hard work into output :). See the screen shot. And Let me if you face any problem while implementing it.
                                               
Main Screen
      Click on button ? it immediately will pop up all your hard work in term of dialog


Android trainner color picker in android
Now Select color

After Selecting Color

1 comment:

  1. Hi! Its a nyc code.... Thank you for that...


    Can you please tell me how to set the width of the dialog.

    ReplyDelete

Feedback always help in improvement. If you have any query suggestion feel free to comment and Keep visiting my blog to encourage me to blogging

Android News and source code