颜色选择条 水平条状

public class ColorSelectBar extends View {

    //控件的高度
    private int mBarHeight;
    //控件的宽度
    private int mBarWidth;
    //定义画笔
    private Paint paint;
    //圆圈的半径
    private int mBarPointerRadius;

    private RectF mBarRect = new RectF();
    //圆圈的圆心坐标
    private int cX, cY;

    //定义线性渲染
    private LinearGradient linearGradient;
    //画圆的画笔
    private Paint circlePaint;

    //渐变的颜色集合
    private static final int[] COLORS = new int[]{0xFF000000, 0xFF808080, 0xFFFFFFFF, 0xFFFF0000, 0xFFFF00FF,
            0xFF0000FF, 0xFF00FFFF, 0xFF00FF00, 0xFFFFFF00, 0xFFFF0000};

    //选择的颜色
    private int selectColor = Color.parseColor("#ff000000");

    //记录是否可以移动
    private boolean mIsMovingPointer;

    //颜色变化的监听器
    ColorChangeListener colorChangeListener;

    public ColorSelectBar(Context context) {
        super(context);
        init(null, 0);
    }

    public ColorSelectBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs, 0);
    }

    public ColorSelectBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs, defStyleAttr);
    }

    private void init(AttributeSet attrs, int defStyle) {
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ColorSelectBar, defStyle, 0);
        final Resources resources = getContext().getResources();
        //获取高度
        mBarHeight = a.getDimensionPixelSize(R.styleable.ColorSelectBar_bar_height, resources.getDimensionPixelSize(R.dimen.bar_height));
        //获取宽度
        mBarWidth = a.getDimensionPixelSize(R.styleable.ColorSelectBar_bar_width, resources.getDimensionPixelSize(R.dimen.bar_width));
        //获取半径
        mBarPointerRadius = a.getDimensionPixelSize(R.styleable.ColorSelectBar_pointer_radius, resources.getDimensionPixelSize(R.dimen.bar_pointer_radius));
        a.recycle();
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.FILL);
        //定义画圆的画笔
        circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //获取mode和size
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        //根据mode来确定size
        if (widthMode == MeasureSpec.EXACTLY) {
            mBarWidth = widthSize - mBarPointerRadius * 2;
        } else if (widthMode == MeasureSpec.AT_MOST) {
            mBarWidth = Math.min(mBarWidth, widthSize);
        }
        //确定高度
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        if (heightMode == MeasureSpec.EXACTLY) {
            mBarHeight = heightSize;
        } else if (heightMode == MeasureSpec.AT_MOST) {
            mBarHeight = Math.min(mBarHeight, heightSize);
        }
        //确定最终大小布局
        setMeasuredDimension(widthSize, mBarPointerRadius * 2);
        //确定矩形的位置
        mBarRect.set(mBarPointerRadius,
                mBarPointerRadius - (mBarHeight / 2),
                mBarWidth + mBarPointerRadius,
                (mBarPointerRadius + (mBarHeight / 2))
        );
        //计算圆心的位置
        cX = mBarWidth + mBarPointerRadius;
        cY = mBarPointerRadius;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (null == linearGradient) {
            linearGradient = new LinearGradient(mBarPointerRadius, 0, mBarWidth + mBarPointerRadius, mBarHeight, COLORS, null, Shader.TileMode.CLAMP);
            paint.setShader(linearGradient);
        }
        canvas.drawRect(mBarRect, paint);        //绘制矩形

        circlePaint.setColor(selectColor);
        canvas.drawCircle(cX, cY, mBarPointerRadius, circlePaint);    //绘制圆圈
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        getParent().requestDisallowInterceptTouchEvent(true);
        int action = event.getAction();
        //只是水平的滑动,故只记录x值的变化
        float dimen;
        dimen = event.getX();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                if (dimen >= mBarPointerRadius && dimen <= mBarPointerRadius + mBarWidth) {
                    mIsMovingPointer = true;
                    drawAgain(dimen);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (mIsMovingPointer) {
                    if (dimen >= mBarPointerRadius
                            && dimen <= (mBarPointerRadius + mBarWidth)) {
                        drawAgain(dimen);
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                mIsMovingPointer = false;
                break;
        }
        return true;
    }


    private int ave(int s, int d, float p) {
        return s + Math.round(p * (d - s));
    }

    //根据位置来计算相应的颜色值
    private int calculateColor(float x) {
        float unit = x / (mBarPointerRadius + mBarWidth);
        if (unit < 0) {
            unit += 1;
        }

        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;

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

    //定义个接口,颜色发生变化的接口监听
    public interface ColorChangeListener {
        public void onColorChanged(int value);
    }

    public void setColorChangeListener(ColorChangeListener colorChangeListener) {
        this.colorChangeListener = colorChangeListener;
    }

    /**
     * 重新绘制
     */
    private void drawAgain(float dimen) {
        cX = Math.round(dimen);
        selectColor = calculateColor(cX);
        invalidate();
        if (null != colorChangeListener)
            colorChangeListener.onColorChanged(selectColor);
    }
}

实现效果类似于:


ps:需要在dimens文件中自定义,颜色条的宽、高和拖动圆形的半径。在attr文件中定义,自定义颜色条的属性,及属性参数。

如:

<declare-styleable name="ColorSelectBar">
        <!--高度-->
        <attr name="bar_height" format="dimension"></attr>
        <!--宽度-->
        <attr name="bar_width" format="dimension"></attr>
        <!--圆圈的半径-->
        <attr name="pointer_radius" format="dimension"></attr>
</declare-styleable>



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值