Skip to main content

Featured post

Simple RecyclerView example with filter option in Android

Hi Guys, Maybe you all are expert in terms of using RecyclerView in android. This blog is simple example for using filter option with RecyclerView adapter. As for now you will instantiate RecyclerView and set the adapter to RecyclerView as following way. RecyclerView list = (RecyclerView) findViewById(R.id.list); list.setLayoutManager(new LinearLayoutManager(this)); list.setHasFixedSize(true); ArrayList&ltNumber&gt numbers = new ArrayList&lt&gt(); String ONEs[] = {"ZERO", "ONE", "TWO", "THREE", "FOUR", "FIVE", "SIX", "SEVEN", "EIGHT", "NINE", "TEN"}; String TENs[] = {"ZERO", "TEN", "TWENTY", "THIRTY", "FOURTY", "FIFTY", "SIXTY", "SEVENTY", "EIGHTY", "NINETY", "HUNDRED"}; String HUNDREDS[] = {"ZERO", "HUNDRED", "TWO HUND

Simple ColorPicker for android.

Sometimes we want to allow user to pick a color from color picker. This post will bring you to two different type of color pickers.

YouTube video:


First one will appear like the following screen shot which is provided by google's android platform.


Code for create this type of dialog

ColorPicker.java
import android.os.Bundle;
import android.app.Dialog;
import android.content.Context;
import android.graphics.*;
import android.view.MotionEvent;
import android.view.View;

public class ColorPicker 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 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;
            
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 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);                        
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;    
invalidate();
}
break;
}
return true;
}
}

public ColorPicker(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");
}
}
Following code will describe how to use this dialog

ColorPickerActivity.java
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;

public class ColorPickerActivity extends Activity implements
  ColorPicker.OnColorChangedListener {
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  this.activity = this;
 } 

 @Override
 public void colorChanged(int color) {  
  ColorPickerActivity.this.findViewById(android.R.id.content)
  .setBackgroundColor(color);
 }

 Activity activity;

 public void getColor(View v) {
  new ColorPicker(activity, ColorPickerActivity.this, Color.WHITE)
    .show();  
 }
}

Second one will appear like the following screen shot.



Code for create this type of dialog

ColorPicker.java
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.Shader;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;

public class ColorPicker extends Dialog {

 public interface OnColorChangedListener {
  void colorChanged(String key, int color);
 }

 private OnColorChangedListener mListener;
 private int mInitialColor, mDefaultColor;
 private String mKey;

 private static class ColorPickerView extends View {
  private Paint mPaint;
  private float mCurrentHue = 0;
  private int mCurrentX = 0, mCurrentY = 0;
  private int mCurrentColor, mDefaultColor;
  private final int[] mHueBarColors = new int[258];
  private int[] mMainColors = new int[65536];
  private OnColorChangedListener mListener;

  ColorPickerView(Context c, OnColorChangedListener l, int color, int defaultColor) {
   super(c);
   mListener = l;
   mDefaultColor = defaultColor;

   // Get the current hue from the current color and update the main
   // color field
   float[] hsv = new float[3];
   Color.colorToHSV(color, hsv);
   mCurrentHue = hsv[0];
   updateMainColors();

   mCurrentColor = color;

   // Initialize the colors of the hue slider bar
   int index = 0;
   for (float i = 0; i < 256; i += 256 / 42) // Red (#f00) to pink
              // (#f0f)
   {
    mHueBarColors[index] = Color.rgb(255, 0, (int) i);
    index++;
   }
   for (float i = 0; i < 256; i += 256 / 42) // Pink (#f0f) to blue
              // (#00f)
   {
    mHueBarColors[index] = Color.rgb(255 - (int) i, 0, 255);
    index++;
   }
   for (float i = 0; i < 256; i += 256 / 42) // Blue (#00f) to light
              // blue (#0ff)
   {
    mHueBarColors[index] = Color.rgb(0, (int) i, 255);
    index++;
   }
   for (float i = 0; i < 256; i += 256 / 42) // Light blue (#0ff) to
              // green (#0f0)
   {
    mHueBarColors[index] = Color.rgb(0, 255, 255 - (int) i);
    index++;
   }
   for (float i = 0; i < 256; i += 256 / 42) // Green (#0f0) to yellow
              // (#ff0)
   {
    mHueBarColors[index] = Color.rgb((int) i, 255, 0);
    index++;
   }
   for (float i = 0; i < 256; i += 256 / 42) // Yellow (#ff0) to red
              // (#f00)
   {
    mHueBarColors[index] = Color.rgb(255, 255 - (int) i, 0);
    index++;
   }

   // Initializes the Paint that will draw the View
   mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
   mPaint.setTextAlign(Paint.Align.CENTER);
   mPaint.setTextSize(12);
  }

  // Get the current selected color from the hue bar
  private int getCurrentMainColor() {
   int translatedHue = 255 - (int) (mCurrentHue * 255 / 360);
   int index = 0;
   for (float i = 0; i < 256; i += 256 / 42) {
    if (index == translatedHue)
     return Color.rgb(255, 0, (int) i);
    index++;
   }
   for (float i = 0; i < 256; i += 256 / 42) {
    if (index == translatedHue)
     return Color.rgb(255 - (int) i, 0, 255);
    index++;
   }
   for (float i = 0; i < 256; i += 256 / 42) {
    if (index == translatedHue)
     return Color.rgb(0, (int) i, 255);
    index++;
   }
   for (float i = 0; i < 256; i += 256 / 42) {
    if (index == translatedHue)
     return Color.rgb(0, 255, 255 - (int) i);
    index++;
   }
   for (float i = 0; i < 256; i += 256 / 42) {
    if (index == translatedHue)
     return Color.rgb((int) i, 255, 0);
    index++;
   }
   for (float i = 0; i < 256; i += 256 / 42) {
    if (index == translatedHue)
     return Color.rgb(255, 255 - (int) i, 0);
    index++;
   }
   return Color.RED;
  }

  // Update the main field colors depending on the current selected hue
  private void updateMainColors() {
   int mainColor = getCurrentMainColor();
   int index = 0;
   int[] topColors = new int[256];
   for (int y = 0; y < 256; y++) {
    for (int x = 0; x < 256; x++) {
     if (y == 0) {
      mMainColors[index] = Color.rgb(
        255 - (255 - Color.red(mainColor)) * x / 255,
        255 - (255 - Color.green(mainColor)) * x / 255,
        255 - (255 - Color.blue(mainColor)) * x / 255);
      topColors[x] = mMainColors[index];
     } else
      mMainColors[index] = Color.rgb(
        (255 - y) * Color.red(topColors[x]) / 255,
        (255 - y) * Color.green(topColors[x]) / 255,
        (255 - y) * Color.blue(topColors[x]) / 255);
     index++;
    }
   }
  }

  @Override
  protected void onDraw(Canvas canvas) {
   int translatedHue = 255 - (int) (mCurrentHue * 255 / 360);
   // Display all the colors of the hue bar with lines
   for (int x = 0; x < 256; x++) {
    // If this is not the current selected hue, display the actual
    // color
    if (translatedHue != x) {
     mPaint.setColor(mHueBarColors[x]);
     mPaint.setStrokeWidth(1);
    } else // else display a slightly larger black line
    {
     mPaint.setColor(Color.BLACK);
     mPaint.setStrokeWidth(3);
    }
    canvas.drawLine(x + 10, 0, x + 10, 40, mPaint);
    // canvas.drawLine(0, x+10, 40, x+10, mPaint);
   }

   // Display the main field colors using LinearGradient
   for (int x = 0; x < 256; x++) {
    int[] colors = new int[2];
    colors[0] = mMainColors[x];
    colors[1] = Color.BLACK;
    Shader shader = new LinearGradient(0, 50, 0, 306, colors, null, Shader.TileMode.REPEAT);
    mPaint.setShader(shader);
    canvas.drawLine(x + 10, 50, x + 10, 306, mPaint);
   }
   mPaint.setShader(null);

   // Display the circle around the currently selected color in the
   // main field
   if (mCurrentX != 0 && mCurrentY != 0) {
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setColor(Color.BLACK);
    canvas.drawCircle(mCurrentX, mCurrentY, 10, mPaint);
   }

   // Draw a 'button' with the currently selected color
   mPaint.setStyle(Paint.Style.FILL);
   mPaint.setColor(mCurrentColor);
   canvas.drawRect(10, 316, 138, 356, mPaint);

   // Set the text color according to the brightness of the color
   if (Color.red(mCurrentColor) + Color.green(mCurrentColor) + Color.blue(mCurrentColor) < 384)
    mPaint.setColor(Color.WHITE);
   else
    mPaint.setColor(Color.BLACK);
   canvas.drawText("Pick", 74, 340, mPaint);

   // Draw a 'button' with the default color
   mPaint.setStyle(Paint.Style.FILL);
   mPaint.setColor(mDefaultColor);
   canvas.drawRect(138, 316, 266, 356, mPaint);

   // Set the text color according to the brightness of the color
   if (Color.red(mDefaultColor) + Color.green(mDefaultColor)
     + Color.blue(mDefaultColor) < 384)
    mPaint.setColor(Color.WHITE);
   else
    mPaint.setColor(Color.BLACK);
   canvas.drawText("Pick", 202, 340,
     mPaint);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
   setMeasuredDimension(276, 366);
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
   if (event.getAction() != MotionEvent.ACTION_DOWN)
    return true;
   float x = event.getX();
   float y = event.getY();

   // If the touch event is located in the hue bar
   if (x > 10 && x < 266 && y > 0 && y < 40) {
    // Update the main field colors
    mCurrentHue = (255 - x) * 360 / 255;
    updateMainColors();

    // Update the current selected color
    int transX = mCurrentX - 10;
    int transY = mCurrentY - 60;
    int index = 256 * (transY - 1) + transX;
    if (index > 0 && index < mMainColors.length)
     mCurrentColor = mMainColors[256 * (transY - 1) + transX];

    // Force the redraw of the dialog
    invalidate();
   }

   // If the touch event is located in the main field
   if (x > 10 && x < 266 && y > 50 && y < 306) {
    mCurrentX = (int) x;
    mCurrentY = (int) y;
    int transX = mCurrentX - 10;
    int transY = mCurrentY - 60;
    int index = 256 * (transY - 1) + transX;
    if (index > 0 && index < mMainColors.length) {
     // Update the current color
     mCurrentColor = mMainColors[index];
     // Force the redraw of the dialog
     invalidate();
    }
   }

   // If the touch event is located in the left button, notify the
   // listener with the current color
   if (x > 10 && x < 138 && y > 316 && y < 356)
    mListener.colorChanged("", mCurrentColor);

   // If the touch event is located in the right button, notify the
   // listener with the default color
   if (x > 138 && x < 266 && y > 316 && y < 356)
    mListener.colorChanged("", mDefaultColor);

   return true;
  }
 }

 public ColorPicker(Context context, OnColorChangedListener listener,
   String key, int initialColor, int defaultColor) {
  super(context);

  mListener = listener;
  mKey = key;
  mInitialColor = initialColor;
  mDefaultColor = defaultColor;
 }

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  OnColorChangedListener l = new OnColorChangedListener() {
   public void colorChanged(String key, int color) {
    mListener.colorChanged(mKey, color);
    dismiss();
   }
  };

  setContentView(new ColorPickerView(getContext(), l, mInitialColor,
    mDefaultColor));
  setTitle("Pick a color");

 }
}
Following code will describe how to use this dialog

ColorPickerActivity.java
package com.example.colorpicker;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;

public class ColorPickerActivity extends Activity implements
  ColorPicker.OnColorChangedListener {
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  this.activity = this;
 } 

 @Override
 public void colorChanged(String str,int color) {  
  ColorPickerActivity.this.findViewById(android.R.id.content)
  .setBackgroundColor(color);
 }

 Activity activity;

 public void getColor(View v) {
  new ColorPicker(activity, this, "", Color.BLACK, Color.WHITE).show(); 
 }
}
xml code for both activity

main.xml
&ltRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".ColorPickerActivity" &gt

    &ltButton
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:onClick="getColor"
        android:text="Button" /&gt

&lt/RelativeLayout&gt
Sample output screen shot for both dialogs.



I hope this post is useful to you. kindly share your feedback as comment here.



Source code on GitHub



Thank You



Comments

  1. Thank you it really worked in AIDE

    ReplyDelete
  2. Please help how can i increase the size of color picker and it appear in full dialog. Because the size is too small than dialog box

    ReplyDelete

Post a Comment

Popular posts from this blog

Simple example of OCRReader in Android.

Hi Friends, Maybe you all heard/used text scanning using camera feature or extracting text from Image. But this sample made it very easy for you. You can made it in very simple line of code. You can download the source code from OCRSample and import the library as a module into your project. Example usage : MainActivity.java public class MainActivity extends AppCompatActivity { private TextView textView; private final int CAMERA_SCAN_TEXT = 0; private final int LOAD_IMAGE_RESULTS = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); textView = findViewById(R.id.textView); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu_main, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSele

Set limit for fraction in decimal numbers in EditText

            Already we know that we can set which type of input the edittext should accept from user using android:inputType="numberDecimal" But there is no predefined function to set the limit for the edittext to How many digit it should accept after the decimal point from user . We can achieve this by using TextWatcher . Full code example. Following program creates a Decimal Filter. DecimalFilter.java import android.text.Editable; import android.text.InputFilter; import android.text.TextWatcher; import android.view.KeyEvent; import android.view.View; import android.view.View.OnKeyListener; import android.widget.EditText; public class DecimalFilter implements TextWatcher { int count= -1 ; EditText et; Activity activity; public DecimalFilter(EditText edittext, Activity activity) { et = edittext; this.activity = activity; } public void afterTextChanged(Editable s) { if (s.length() > 0) { String str = et.getText().toString(); et.setOnKeyListener(new OnKeyL

Simple example of using Spinner in Kotlin | Android

Though Kotlin has lot massive features to speedup the development time, here is the simple way of using Spinner in Android. In Kotlin we don't need to declare and initialize Spinner. We can simply access the id of Spinner from xml. Ex : import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.view.View import android.widget.AdapterView import android.widget.ArrayAdapter import android.widget.Toast import android.widget.Toast.LENGTH_LONG import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //String array. val myStrings = arrayOf("One", "Two", "Three", "Four", "Five") //Adapter for spinner mySpinner.adapter = ArrayAdapter(this, android.R.layout.simple_spinner_dropdown_i