Skip to content
Stanislav Georgiev edited this page Aug 16, 2020 · 1 revision

Color Picker Wiki

Here you will find useful information about the color picker, how it is made and how it work. You will learn about all available properties and there use in each of the color windows. You will learn about color windows and how to attach text views that will display the value of the selected color in different color models, and create custom color pickers. You will understand how to modify or create your own color window class in case you want another color picker instead using the the available ones. Once there are color windows available a color picker can be made by combining different color windows and text views using the Updater class where all the modules are attached.


Structure



Base class is the parent of all color windows classes and each color window class extends it through the color component classes. The Base class has all properties that are used by all color windows.

Color component classes handle all the functionality to each of the 3 available component individually.For example the component classes takes care of moving the selector, which shows current selected color by the user. There are three available component classes:

  • Rectangular
  • Slider
  • Circular

Color Window(Module) classes extends the component classes, there are size available color windows.Each color window class takes care of caching two bitmaps - baseLayer and colorLayer that are used when drawing the view. Those bitmaps are cached that way paths and shapes are not drawn each time any of the color windows that are attached is updated but instead only the cached bitmaps is drawn when needed. There are six available color window classes:

  • SliderA
  • SliderH
  • SliderV
  • CircularHS
  • RectangularSV
  • RectangularSL

Color Components

Color components are used to create color windows and eventually creating color pickers, all of them extend the abstract class Base. If needed, a new color component type can be created by extending the Base class. The following three color components are presented in the library:

  • Rectangular - 2D color components in a form of a rectangle
  • Circular - 2D color components in a form of a circle
  • Slider - 1D color components in a form of a rectangle

1D - one dimensional meaning only one value can be changed for the color component
2D - two dimensional meaning two values can be changed for the color component


alt text

Color Component Properties

There are properties available to all color components, set in the Base class and there are properties available only to the particular color component type Circular, Slider or Rectangular. For example the the Slider component has type property that determines if the slider is vertical or horizontal, and each of the three components has different range values, that is changed when the user moves the selector. Below is shown an image of a selector for particular color window, and all the parts that form a color picker.

List with properties available to all color components extending the Base class

  • Selector circle properties

    • selector_color - stroke color for the selector
    • selector_radius - selector radius(determines the selector size)
    • selector_stroke_width - stroke width(determines stroke thickness)
  • Corner radius properties

    • corner_radius - radius for all four corners
    • corner_radius_upper_left - radius for the upper left corner
    • corner_radius_upper_right - radius for the upper right corner
    • corner_radius_lower_left - radius for the lower left corner
    • corner_radius_lower_right - radius for the lower right corner
  • Border properties

    • border_color - stroke color for the border surrounding the color picker window
    • border_stroke_width - stroke width(determines stroke thickness)

Circular color component properties

  • Range properties
    • distance_range_lower - lower range for the distance
    • distance_range_upper - upper range for the distance
    • angle_range_lower - lower range for the angle
    • angle_range_upper - upper range for the angle

Rectangular color component properties

  • Range properties
    • vertical_range_lower - lower range for the vertical direction
    • vertical_range_upper - upper range for the vertical direction
    • horizontal_range_lower - lower range for the horizontal direction
    • horizontal_range_upper - upper range for the horizontal direction

Slider color component properties

  • Range properties
    • range_lower - lower range for both slider types
    • range_upper - upper range for both slider types
    • type - show the slider type: vertical or horizontal

Color Windows

Color windows(modules) are used to create each of the custom color picker by combining different color windows and attaching them using the Updater class. There are six available color windows that are used to generate the three color pickers presented in the library, those are:

  • SliderA changes A(alpha) value for RGBA color model
  • SliderH changes H(hue) value for HSV, HSL and HWB color models
  • SliderV changes V(value) value for the HSV color model
  • CircularHS changes the H(hue) and S(saturation) values for the HSV color model
  • RectangularSV changes the S(saturation) and V(value) for the HSV color model
  • RectangularSL changes the S(saturation) and L(lightness) for the HSL color model

Each of the color windows are named after the values they change and the particular color model in which they are used. For example the RectangularSV is used to change the S(Saturation) and V(values) for the HSV color model. On the image below you can see the color windows visually and the values they change in each dimension.


ColorPickers

Color picker are made of multiple color windows combined with text view that shows values for particular color model. Library consist of three pre-made color windows,those are:

  • RectangularHSV
  • RectangularHSL
  • CircularHSV

RectangularHSV Color Picker

RectangularHSV color picker is made of three color windows: RectangularSV, SliderH and SliderA. This particular color picker is made in order to change the color model HSV(Hue, Saturation, Value), once values are changed they are converted to RGBA color model and from there it is converted to the other color models such as HSL, HWB, CMYK and HEX. RectangularSV color windows changes the S(Saturation) and V(Value) values, SliderA changes the A(Alpha) value and the SliderH changes the H(Hue). Alpha changes in range of [0,255], Hue values is in range of [0,360] and the S(Saturation) and V(Value) values are in range [0,100].

alt text

RectangularHSL Color Picker

RectangularHSL color picker is made of three color windows: RectangularSL, SliderH and SliderA. This particular color picker is made in order to change the color model HSL(Hue, Saturation, Lightness), once values are changed they are converted to RGBA color model and from there it is converted to the other color models such as HSV, HWB, CMYK and HEX. RectangularSL color windows changes the S(Saturation) and L(Lightness) values, SliderA changes the A(Alpha) value and the SliderH changes the H(Hue). Alpha changes in range of [0,255], Hue values is in range of [0,360] and the S(Saturation) and L(Lightness) values are in range [0,100].

alt text

CircularHSV Color Picker

CircularHSV color picker is made of three color windows: CirsularHS, SliderV and SliderA. This particular color picker is made in order to change the color model HSV(Hue, Saturation, Value), once values are changed they are converted to RGBA color model and from there it is converted to the other color models such as HSL, HWB, CMYK and HEX. CircularHS color windows changes the H(Hue) and S(Saturation) values, SliderA changes the A(Alpha) value and the SliderV changes the V(Value). Alpha changes in range of [0,255], Hue values is in range of [0,360] and the S(Saturation) and V(Value) values are in range [0,100].

alt text


TextView

To associate TextView object as color picker component a color format must be specified either with attachment to the Updater via the attach methods, or as tag property when xml is used to create the text view or set the tag manually using the setTag() method for Java/Kotlin. TextViews objects can show the current selected color in different color model formats. If we want the ability to change the text value instead of just showing it we can use the EditText which by the way extends the TextView class and is also supported by the library.

There are two supported formats for holding color model values:

  • single value - single value from the whole color model(for example the value R from RGBA color model)
  • multiple values - multiple values that includes all values from the color model as a whole

Available TextView types for the two formats:

  • multiple values

    • RGB (Red, Green, Blue)
    • RGBA (Red, Green, Blue, Alpha)
    • HSV (Hue, Saturation, Value)
    • HSL (Hue, Saturation, Lightness)
    • HWB (Hue, White, Black)
    • CMYK (Cyan, Magenta, Yellow, Black)
    • HEX Hexadecimal
    • HEXA Hexadecimal with Alpha
  • single value

    • RGBA_R Red from RGBA
    • RGBA_G Green from RGBA
    • RGBA_B Blue from RGBA
    • RGBA_A Alpha from RGBA
    • HSV_H Hue from HSV
    • HSV_S Saturation from HSV
    • HSV_V Value from HSV
    • HSL_H Hue from HSL
    • HSL_S Saturation from HSL
    • HSL_L Lightness from HSL
    • HWB_H Hue from HWB
    • HWB_W White from HWB
    • HWB_B Black from HWB
    • CMYK_C Cyan from CMYK
    • CMYK_M Magenta from CMYK
    • CMYK_Y Yellow from CMYK
    • CMYK_K Black from CMYK

Below is example on how to set the tag property using the attach method of the Updater class. You can also use the constructor of the Updater class to attach the text views, for that check the Updater section of the wiki page.

// create color convert, that will convert colors from one color model to another
val colorConverter: ColorConverter = ColorConverter("#1f538cb5")

// create updater object, that will update all color window and text views
val updater: Updater = Updater(colorConverter)

// attach TextView object and specify it to holds the r(Red) value from RGBA color model
val textView: TextView = findViewById(R.id.text_view);
update.attachTextView(textView, Updater.TYPE_RGBA_R)

If a TextView object is used in separate layout file, when creating a custom color picker for example it is not convenient to set the type manually, so instead the tag property can be used. You set the tag property in your xml file for your TextView object, and when the updater is attached to the color picker, the tag property value will be checked and set to as corresponding type automatically. Tutorial is available on the paragraph how to create color picker

Here is example how to set r(red) value for RGBA color model using the tag property in xml.

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:tag="rgba_r" />

ColorConverter

ColorConverter class is responsible for the conversion of currently selected color into different color models. Those color model values can be used by different TextView objects to display the current selected color value. The class has methods that lets you get the current selected color in different color model formats - single or multiple value formats.

Supported color model that are used in the conversion by default:

  • RGBA - Red, Green, Blue, Alpha
  • CMYK - Cyan, Magenta, Yellow, Black
  • HSV - Hue, Saturation, Value
  • HSL - Hue, Saturation, Lightness
  • HWB - Hue, White, Black
  • HEX - hexadecimal representation of the rgb color model

Default selected color for the color pickers can be set as first argument, when new ColorConverter object is created. The argument can be any object of the supported color models classes, or use multiple arguments for example r(red), g(green), b(blue) and a(alpha) values to set values using the RGBA color model.

Example how to set default color using multiple values.

// create using H(Hue), S(Saturation), V(Value), A(Alpha) values 
val colorConverter: ColorConverter = ColorConverter(h = 120, s = 20, v = 41, a = 31)

Example how to set default color using HSV object.

// create HSV object
val hsv: HSV = HSV(120, 20, 41)
val colorConverter: ColorConverter = ColorConverter(hsv)

ColorHolder

ColorHolder class is responsible for keeping and updating the currently selected color and the base color for a particular group of color pickers and components. Holder objects are attached to the Updater class and thus receive update calls via the setter methods. There are also two more values for selected and base colors with opacity set to zero (alpha: 0), they are user by the color windows when they are drawn.

  • selected color - currently selected color by the user for the group of color windows and text views
  • base color - color that is used by the color windows, when they are drawn (HUE color)

Updater

Updater class is responsible for updating the content of all attached color pickers, text views and color windows responsively, so the change in one view will trigger change in all other color picker components. That way you can attach multiple views and update all of them.

Updater constructor receive multiple arguments, where you can specify color converter, color holder, color windows and text views. That way the updater class can communicate with them. Below is a example of setting all arguments for the Updater class, in case we have a color windows: rectangularSV and text view: textView.

// get text view and color window
val textView: TextView = findViewById(R.id.text_view)
val rectangularSV: RectangularSV = findViewById(R.id.color_window)

// create color converter
val colorConverter: ColorConverter = ColorConverter(160, 73, 184, 50)

// create color holder
val colorHolder: ColorHolder = ColorHolder()

// set the color windows in a list (we can add as many color windows to the list as we want)
val colorWindows: MutableList<Base> = mutableListOf(rectangularSV)

// set the text views in a hash map with the text views as key, and value as the type (we can add as many text view to the hashmap as we want)
val textViews: HashMap<TextView, Int> = hashMapOf(textView to Updater.TYPE_RGBA)

// create a updater using the arguments generated above
val updater:Updater = Updater(colorConverter, colorHolder, colorWindows, textViews)

Another way to attach text views and color windows is using the attach methods presented in the Update class. There are many different variations of attaching text views.

val textView: TextView = findViewById(R.id.text_view)
val rectangularSV: RectangularSV = findViewById(R.id.color_window)

val updater: Updater = Updater()
update.attachTextView(textView, Updater.TYPE_HSL_H)
update.attachColorWindows(rectangularSV)

Color Group

Color group is formed by different color pickers and views(text views, color windows), that together formed a color group.

The Updater class handles the updates from the view where the change has happened and updates the other views with there corresponding values. For example if attached EditText object is updated by the user by typing new value, the Updater class will trigger changes to all the color windows and text views that are connected via the Updater class.

The ColorConverter class handles all the conversions from one color model to all other color models that are included. For example if the H(Hue) value for HSV color model is changed, then that particular model is converted to RGBA color model and from there it is converted to the other color models: HSL, HWB, CMYK and HEX. That way if any attached text view is using for example the format CMYK_M for holding the single M(magenta) value, then once the ColorConverter class converts from RGBA to all other color models, the values for the CMYK color model can be extracted and displayed in that particular text view.

Color Pickers are formed by different views(color windows and text views) that are fully customisable depending on your needs. For example you can attach RectangularSV color windows combined with SliderH color window in order to be able to update the whole HSV color model. With that said you can also add TextView objects where you can display the current selected color by the user.

alt text

TUTORIAL: Creating Custom Color Picker

I) First step of creating your first color picker is the XML file, that will include the separate views forming the color picker.

Included view can be one of those two types: Base(color windows classes: SliderA,SliderH,SliderV,CircularHS,RectangularSV,RectangularSL) or TextView(EditText).

  • Base - view that shows visual information about the currently selected color
  • TextView - used to displays actual value of the color which is currently being selected

Here is a example of xml file that includes two components the first one is RectangularSV color window and second one is EditText(since it extend the TextView class it can also be used). We specify the color format for the edit text using the tag property, we set it to hex which will diplay the hexadecimal value of the RGB color model.

Create xml file named custom_color_picker.xml in the layout directory: ../res/layout/custom_color_picker.xml and put the following code:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <com.slaviboy.colorpicker.module.rectangular.RectangularSV
        android:id="@+id/rectangularSV"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:corner_radius="10dp"
        app:layout_constraintBottom_toBottomOf="@+id/hex_value"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="packed"
        app:selector_radius="0.06vh"
        app:selector_stroke_width="0.03vh" />

    <EditText
        android:id="@+id/hex_value"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:tag="hex"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/rectangularSV" />
</merge>

II) Second step is the creation of class named CustomColorPicker.kt that extends the class ColorPicker from the library, and calls the method setViews() in all constructors, with second argument the xml file created from the previous step that will be inflated, when the view is created.

Create kotlin file named CustomColorPicker.kt in java directory and put the following code:

import android.content.Context
import android.util.AttributeSet
import com.slaviboy.colorpicker.main.ColorPicker

class CustomColorPicker : ColorPicker {
    constructor(context: Context) : super(context) {
        init(context)
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        init(context)
    }

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        init(context)
    }

    private fun init(context: Context) {
        setViews(context, R.layout.custom_color_picker)
    }
}

III) Third step is to include the color picker in your layout

For example if you want, you can create a color picker in your activity_main.xml file (or add it wherever you want to add your custom color picker). Don`t forget to user your own package name by replacing com.slaviboy.colorpicker.CustomColorPicker with the package name of your current project where you created your CustomColorPicker class.

   <com.slaviboy.colorpicker.CustomColorPicker
        android:id="@+id/picker"
        android:layout_width="250dp"
        android:layout_height="210dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent" />

IV) Fourth step is to associate the color picker to particular Updater and ColorConverter.

Every color picker or view(TextView or Color Window) must be associated in order to be updated. The color converter object is set as argument to the updater class otherwise default color converter is set.

val customColorPicker: CustomColorPicker = findViewById(R.id.picker)

// create color converter with default selected color: RGBA(160, 73, 184, 50)
val colorConverter: ColorConverter = ColorConverter(160, 73, 184, 50)

// create updater object, that will update all color window and text views
val updater: Updater = Updater(colorConverter)

// attach updater to the color picker (that way there is no need to attach each and every text view and color window from the CustomColorPicker)
customColorPicker.attach(updater)