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

ColorPicker

一款仿Photoshop取色器的Android版取色器。

github地址:https://github.com/relish-wang/ColorPicker

前言

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

注:

初始颜色传入

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

  • 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)

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

屏幕点击事件onTrackballEvent

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

最后汇总一下,今天这篇文章主要讲了,ColorPickerView的初始颜色传入+颜色改变监听。下一篇将讲解ColorPickerDialog的主要代码,敬请期待。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容