Color Picker | Android Color Picker view to set Color to Bulb View
Published December 19, 2020In any mobile application major role will be took UI design, there Color themes are very important part. Pick a color from a picker to apply dynamic themes to the app will be more tricky.
In this post we are going to create a application to pick a color from RGB values or a Color Picker View.
What is Android Color, How it be declare it value?
A Color is a 32 bit integer value in Andorid color system. These 32 bit integer value could be divide into 4 bytes, those are
Alpha - 1 byte (8 bits)
Red - 1 byte (8 bits)
Green - 1 byte (8 bits)
Blue - 1 byte (8 bits)
Combining these four values will be called as RGB or ARGB values.
Let's get started
Step 1: Create Android application
Step 2: Create Custom Color Picker View
PickerView.class
package com.rrtutors.colorpicker;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
public class PickerView extends View {
private Paint mPaint;
private Paint mCenterPaint;
private int[] mColors;
private ColorPickerDialog.OnColorChangedListener mListener;
public PickerView(Context context) {
super(context);
}
public PickerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public PickerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void init(Context c, ColorPickerDialog.OnColorChangedListener l, int color)
{
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(dpToPx(64));
mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mCenterPaint.setColor(color);
mCenterPaint.setStrokeWidth(5);
}
PickerView(Context c, ColorPickerDialog.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(dpToPx(64));
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.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.bulb),0,0, mCenterPaint);
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);*/
// canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.bulb), 0,0, 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 int CENTER_X = dpToPx(132);
private int CENTER_Y = dpToPx(132);
private int CENTER_RADIUS = dpToPx(40);
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 dpToPx(int dp) {
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
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.hypot(x, y) <= CENTER_RADIUS;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mTrackingCenter = inCenter;
if (inCenter) {
mHighlightCenter = true;
invalidate();
mListener.colorChaning(mCenterPaint.getColor());
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();
mListener.colorChaning(mCenterPaint.getColor());
}
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;
}
}
|
Step 3: Create a Dialog to show the created Color Picker view
package com.rrtutors.colorpicker;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.widget.ImageView;
public class ColorPickerDialog extends Dialog {
ImageView img_bulb;
public interface OnColorChangedListener {
void colorChanged(int color);
void colorChaning(int color);
}
private OnColorChangedListener mListener;
private int mInitialColor;
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) {
// img_bulb.setBackgroundColor(color);
img_bulb.setColorFilter(color, android.graphics.PorterDuff.Mode.MULTIPLY);
mListener.colorChanged(color);
dismiss();
}
@Override
public void colorChaning(int color) {
img_bulb.setColorFilter(color, android.graphics.PorterDuff.Mode.SRC_IN);
// img_bulb.setBackgroundColor(color);
}
};
setContentView(R.layout.color_dialog);
PickerView colorpicker=findViewById(R.id.colorpicker);
img_bulb=findViewById(R.id.img_bulb);
colorpicker.init(getContext(), l, mInitialColor);
//setContentView(new ColorPickerView();
setTitle("Pick Color, Click the Dot");
}
}
|
color_dialog.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="400dp"
android:layout_height="400dp">
<com.example.colorpickerandroid.PickerView
android:id="@+id/colorpicker"
android:layout_width="match_parent"
android:layout_centerInParent="true"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/img_bulb"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_centerInParent="true"
android:src="@drawable/ic_light_bulb"
/>
</RelativeLayout>
|
Step 4: Now update MainActivity.java and its related xml files.
package com.rrtutors.colorpicker;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {
SeekBar SeekA;
SeekBar SeekR;
SeekBar SeekG;
SeekBar SeekB;
TextView ShowColor;
ImageView bulb_imgview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SeekA=findViewById(R.id.seekA);
SeekR=findViewById(R.id.seekR);
SeekG=findViewById(R.id.seekG);
SeekB=findViewById(R.id.seekB);
//Reference the TextView
ShowColor=findViewById(R.id.textView);
bulb_imgview=findViewById(R.id.bulb_imgview);
SeekA.setOnSeekBarChangeListener(this);
SeekR.setOnSeekBarChangeListener(this);
SeekG.setOnSeekBarChangeListener(this);
SeekB.setOnSeekBarChangeListener(this);
Button btn_show=findViewById(R.id.btn_show);
btn_show.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
show();
}
});
}
//Satisfy the implements
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
//get current ARGB values
int A=SeekA.getProgress();
int R=SeekR.getProgress();
int G=SeekG.getProgress();
int B=SeekB.getProgress();
//Reference the value changing
int id=seekBar.getId();
//Get the chnaged value
if(id == com.rrtutors.colorpicker.R.id.seekA)
A=progress;
else if(id == com.rrtutors.colorpicker.R.id.seekR)
R=progress;
else if(id == com.rrtutors.colorpicker.R.id.seekA)
G=progress;
else if(id == com.rrtutors.colorpicker.R.id.seekA)
B=progress;
//Build and show the new color
// bulb_imgview.setBackgroundColor(Color.argb(A,R,G,B));
bulb_imgview.setColorFilter(Color.argb(A,R,G,B), android.graphics.PorterDuff.Mode.SRC_IN);
//show the color value
ShowColor.setText("0x"+String.format("%02x", A)+String.format("%02x", R)
+String.format("%02x", G)+String.format("%02x", B));
//some math so text shows (needs improvement for greys)
ShowColor.setTextColor(Color.argb(0xff,255-R,255-G,255-B));
}
public void onStartTrackingTouch(SeekBar seekBar) {
//Only required due to implements
}
public void onStopTrackingTouch(SeekBar seekBar) {
//Only required due to implements
}
private void show()
{
ColorDrawable cd = (ColorDrawable) ShowColor.getBackground();
int colorCode = cd.getColor();
//pick a color (changed in the UpdateColor listener)
new ColorPickerDialog(MainActivity.this, new UpdateColor(), colorCode).show();
}
public class UpdateColor implements ColorPickerDialog.OnColorChangedListener {
public void colorChanged(int color) {
bulb_imgview.setColorFilter(color, android.graphics.PorterDuff.Mode.SRC_IN);
//show the color value
ShowColor.setText("0x"+String.format("%08x", color));
SeekA.setProgress(Color.alpha(color));
SeekR.setProgress(Color.red(color));
SeekG.setProgress(Color.green(color));
SeekB.setProgress(Color.blue(color));
}
@Override
public void colorChaning(int color) {
}
}
}
|
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_margin="5dp"
>
<TextView
android:id="@+id/labelA"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="A"
android:textAppearance="?android:attr/textAppearanceMedium" />
<SeekBar
android:id="@+id/seekA"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/labelA"
android:layout_toRightOf="@id/labelA"
android:max="255"
android:progress="255" />
<TextView
android:id="@+id/labelR"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/labelA"
android:text="R"
android:textAppearance="?android:attr/textAppearanceMedium" />
<SeekBar
android:id="@+id/seekR"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/labelR"
android:layout_below="@+id/seekA"
android:layout_toRightOf="@+id/labelR"
android:max="255"
android:progress="255" />
<TextView
android:id="@+id/labelG"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/labelR"
android:text="G"
android:textAppearance="?android:attr/textAppearanceMedium" />
<SeekBar
android:id="@+id/seekG"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/labelG"
android:layout_below="@+id/seekR"
android:layout_toRightOf="@+id/labelG"
android:max="255"
android:progress="255" />
<TextView
android:id="@+id/labelB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/labelG"
android:text="B"
android:textAppearance="?android:attr/textAppearanceMedium" />
<SeekBar
android:id="@+id/seekB"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/labelB"
android:layout_below="@+id/seekG"
android:layout_toRightOf="@+id/labelB"
android:max="255"
android:progress="255" />
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="200dp"
android:layout_centerHorizontal="true"
android:layout_height="wrap_content"
android:layout_below="@+id/labelB"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/labelB"
android:layout_centerHorizontal="true"
android:background="@android:color/white"
android:padding="16dp"
android:text="0xffffffff"
android:textAlignment="center"
android:textColor="@android:color/black"
android:textSize="22dp" />
<ImageView
android:id="@+id/bulb_imgview"
android:layout_width="120dp"
android:layout_gravity="center"
android:src="@drawable/ic_light_bulb"
android:layout_margin="10dp"
android:layout_height="120dp" />
</LinearLayout>
<Button
android:id="@+id/btn_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Pick From Picker"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_margin="30dp"
/>
</RelativeLayout>
|
Step 5: Run application and check the color for bulb on selecting the color from color Picker view.
Article Contributed By :
|
|
|
|
1598 Views |