【Android自定义View】仿Photoshop取色器ColorPicker(三)

来源:互联网 发布:java行业发展前景 编辑:程序博客网 时间:2024/06/06 01:16

ColorPicker

一款基于HSV颜色空间的仿Photoshop取色器的Android版颜色拾取器。

github地址:ColorPicker

前言

上一篇已经简单介绍了ColorPicker的核心自定义控件ColorPickerView的绘制流程。接下来我们详细解析一下ColorPickerView的监听事件相关代码。

注:
- 1 如果你对HSV颜色空间和RGB颜色空间不够熟悉的话,请参看该系列的第一篇文章——仿Photoshop取色器ColorPicker(一)
- 2 如果你对ColorPickerView的绘制流程不熟悉的话 ,请参看该系列的第二篇文章仿Photoshop取色器ColorPicker(二)

初始颜色传入

在讲颜色改变监听之前,先来讲讲初始颜色传入时,代码的变化吧!

  • 1 先把RGB颜色转化成HSV三个值
  • 2 刷新页面invalidate

说明:调用invalidate后,View会触发onDraw()方法,因此两个调色板会根据现在的HSV值绘制当前显示的色板以及指示器的位置。

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();}

颜色改变监听事件

在选择颜色过程中,会触发两种监听事件:轨迹球拖拽事件(onTrackballEvent)、屏幕点击事件(onTouchEvent)

轨迹球拖拽事件onTrackballEvent

观察这边的代码,这里分为两种情况处理:

  • 当前触点在[饱和度灰度调色板]上
    • 根据x、y坐标获得sat(饱和度)、val(灰度)值(并且做了边界处理)
  • 当前触点在[色相调色板]上
    • 根据y轴坐标获得hue(色相)值 (并且做了边界处理)

最后再将HSV值换算成RGB值,通过监听器回调给上一级(ColorPickerDialog)

@Overridepublic 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);}

屏幕点击事件onTrackballEvent

  • 1 监听了手指的DOWN、UP、MOVE的事件
  • 2 具体处理逻辑在moveTrackersIfNeeded()方法中
    • 2.1 先判断触点是否在调色板内
    • 2.2 然后根据调色板更新对应的sat、val值或hue值
  • 3 根据是否更新了颜色进行监听回调
  • 4 刷新页面invalidate();
@Overridepublic 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;}

最后汇总一下,今天这篇文章主要讲了,ColorPickerView的初始颜色传入+颜色改变监听。下一篇将讲解ColorPickerDialog的主要代码:【Android自定义View】仿Photoshop取色器ColorPicker(四)完结篇

原创粉丝点击