Color Picker | Android Color Picker view to set Color to Bulb View

Published December 19, 2020


In 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.

 

Color Picker Bulb view

 

 


Article Contributed By :
https://www.rrtutors.com/site_assets/profile/assets/img/avataaars.svg

648 Views

Subscribe For Daily Updates

Flutter Questions
Android Questions