ColorPicker
An Android color picker based on HSV color space, which imitates Photoshop color picker.
github address: ColorPicker
Preface
The last article has been briefly introduced. ColorPicker Core custom controls ColorPickerView Drawing process. Next, let's analyze it in detail. ColorPickerView Monitor event related code.
Note:
- If you are not familiar with HSV color space and RGB color space, please refer to the first article in this series.—— Photoshop Colour Picker (I)
- 2 If you are not familiar with the drawing process of Color PickerView, see the second article in this series. Photoshop Colour Picker (II)
Initial color input
Before we talk about color change monitoring, let's talk about how the code changes when the initial color is introduced.
- First convert RGB color to HSV three values
- 2 Refresh page invalidate
Description: After invoking invalidate, View triggers the onDraw() method, so the two palettes draw the current display palette and the location of the indicator based on the current HSV value.
public void setColor(int color) {
setColor(color, false);
}
public void setColor(int color, boolean callback) {
float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
mHue = hsv[0];
mSat = hsv[1];
mVal = hsv[2];
if (callback && mListener != null) {
mListener.onColorChanged(Color.HSVToColor(new float[]{mHue, mSat, mVal}));
}
invalidate();
}
Colour Change Monitor Event
In the process of color selection, two kinds of listening events are triggered: onTrackball Event and onTouchEvent.
Trackball drag event onTrackball Event
Looking at the code here, there are two cases to deal with:
- The current contact is on the saturation gray palette
- Sat (saturation) and val (gray level) values are obtained from x and y coordinates (and boundary treatment is done)
- The current contact is on the [color palette]
- Hue (hue) values are obtained from y-axis coordinates (and boundary treatment is done)
Finally, the HSV value is converted to RGB value, which is called back to the previous level (ColorPickerDialog) by the listener.
@Override
public boolean onTrackballEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
boolean isUpdated = false;
if (event.getAction() == MotionEvent.ACTION_MOVE) {
switch (mLastTouchedPanel) {
case PANEL.SAT_VAL:
float sat, val;
sat = mSat + x / 50f;
val = mVal - y / 50f;
if (sat < 0f) {
sat = 0f;
} else if (sat > 1f) {
sat = 1f;
}
if (val < 0f) {
val = 0f;
} else if (val > 1f) {
val = 1f;
}
mSat = sat;
mVal = val;
isUpdated = true;
break;
case PANEL.HUE:
float hue = mHue - y * 10f;
if (hue < 0f) {
hue = 0f;
} else if (hue > 360f) {
hue = 360f;
}
mHue = hue;
isUpdated = true;
break;
}
}
if (isUpdated) {
if (mListener != null) {
mListener.onColorChanged(Color.HSVToColor(new float[]{mHue, mSat, mVal}));
}
invalidate();
return true;
}
return super.onTrackballEvent(event);
}
Screen Click Event onTrackballEvent
- 1 monitored the events of DOWN, UP and MOVE of finger
- 2. Specific processing logic in moveTrackersIfNeeded() method
- 2.1 First determine if the contact is in the palette.
- 2.2 Then update the corresponding sat, val or hue values according to the palette
- 3 Monitor callback based on whether the color has been updated or not
- Refresh page invalidate();
@Override
public boolean onTouchEvent(MotionEvent event) {
boolean isUpdated = false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mStartTouchPoint = new Point((int) event.getX(), (int) event.getY());
isUpdated = moveTrackersIfNeeded(event);
break;
case MotionEvent.ACTION_MOVE:
isUpdated = moveTrackersIfNeeded(event);
break;
case MotionEvent.ACTION_UP:
mStartTouchPoint = null;
isUpdated = moveTrackersIfNeeded(event);
break;
}
if (isUpdated) {
if (mListener != null) {
mListener.onColorChanged(Color.HSVToColor(new float[]{mHue, mSat, mVal}));
}
invalidate();
return true;
}
return super.onTouchEvent(event);
}
private boolean moveTrackersIfNeeded(MotionEvent event) {
if (mStartTouchPoint == null) return false;
boolean update = false;
int startX = mStartTouchPoint.x;
int startY = mStartTouchPoint.y;
if (mHueRect.contains(startX, startY)) {
mLastTouchedPanel = PANEL.HUE;
mHue = pointToHue(event.getY());
update = true;
} else if (mSatValRect.contains(startX, startY)) {
mLastTouchedPanel = PANEL.SAT_VAL;
float[] result = pointToSatVal(event.getX(), event.getY());
mSat = result[0];
mVal = result[1];
update = true;
}
return update;
}
In conclusion, today's article focuses on the initial color input + color change monitoring of ColorPickerView. The next article will explain the main code of ColorPickerDialog. Please look forward to it.