自定义view:颜色选择器\drawBitmap / seekbar

一、seekbar简单的实现方式:

  • 背景使用色带图片
  • 进度条设置透明
  • 滑块按正常设置
<SeekBar
    android:id="@+id/colorPickerSeekbar"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerVertical="true"
    android:background="@drawable/color_background"
    android:max="30"
    android:progress="5"
    android:progressDrawable="@android:color/transparent"
    android:thumb="@drawable/slider_bar" />

二、自定义view:

attrs.xml :

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="ColorPickerView">
        <attr name="indicatorSrc" format="reference" /><!--指示器资源-->
        <attr name="rx" format="dimension" /><!--rx-->
        <attr name="ry" format="dimension" /><!--ry-->
    </declare-styleable>

</resources>

ColorPickerView:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;


public class ColorPickerView extends View {
    private static final String TAG = ColorPickerView.class.getSimpleName();

    private static final int DEFAULT_WIDTH = 100;
    private static final int DEFAULT_HEIGHT = 100;
    private final float mRx, mRy;
    private final Paint mBgPaint;
    private final Paint mPointerPaint;
    private RectF mRect;
    private Bitmap mBitmap;
    private LinearGradient mLinearGradient;
    private int[] mColors = new int[]{
            Color.parseColor("#FFB620E0"),
            Color.parseColor("#FF6236FF"),
            Color.parseColor("#FF0091FF"),
            Color.parseColor("#FF6DD400"),
            Color.parseColor("#FFF7B500"),
            Color.parseColor("#FFFA6400"),
            Color.parseColor("#FFE02020")
    };
    private Canvas mBitmapCanvas;
    private Bitmap mSlideBitmap;
    private RectF mSlideRect;
    private int mSlideSize;
    private final PaintFlagsDrawFilter mPaintFlagsDrawFilter;
    private int mSlideResId;

    public ColorPickerView(Context context) {
        this(context, null);
    }

    public ColorPickerView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, -1);
    }

    public ColorPickerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ColorPickerView);
        mRx = array.getDimension(R.styleable.ColorPickerView_rx, 4);
        mRy = array.getDimension(R.styleable.ColorPickerView_ry, 4);
        mSlideResId = array.getResourceId(R.styleable.ColorPickerView_indicatorSrc,
                R.drawable.img_carsetting_ambient_light_slider_bar);
        array.recycle();

        mBgPaint = new Paint();
        mBgPaint.setAntiAlias(true);
        mBgPaint.setFilterBitmap(true);
        mPointerPaint = new Paint();
        mPointerPaint.setAntiAlias(true);
        mPointerPaint.setFilterBitmap(true);
        mPaintFlagsDrawFilter = new PaintFlagsDrawFilter(0,
                Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = getProperSize(DEFAULT_WIDTH, widthMeasureSpec);
        int height = getProperSize(DEFAULT_HEIGHT, heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    private int getProperSize(int defaultSize, int measureSpec) {
        int result;
        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);

        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            result = defaultSize;
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size);
            }
        }

        return result;
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        mRect = new RectF(0, 0, w, h);
        mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mBitmapCanvas = new Canvas(mBitmap);

        mLinearGradient = new LinearGradient(
                mRect.left, mRect.top + (mRect.bottom - mRect.top) / 2,
                mRect.right, mRect.top + (mRect.bottom - mRect.top) / 2,
                mColors,
                null,
                Shader.TileMode.CLAMP
        );

        mSlideBitmap = BitmapFactory.decodeResource(getResources(), mSlideResId);
        mSlideSize = Math.min(w, h);
        mSlideRect = new RectF(0, 0, mSlideSize, mSlideSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.setDrawFilter(mPaintFlagsDrawFilter);

        //绘制颜色条背景
        mBgPaint.setShader(mLinearGradient);
        mBitmapCanvas.drawRoundRect(mRect, mRx, mRy, mBgPaint);
        mBgPaint.setShader(null);
        canvas.drawBitmap(mBitmap, mRect.left, mRect.top, mBgPaint);

        //绘制指示器
        canvas.drawBitmap(mSlideBitmap, null, mSlideRect, mPointerPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float ex = event.getX();
        float bitmapX;
        float bitmapY;
        if (ex <= mRect.left + mSlideSize / 2.0f) {
            bitmapX = mSlideSize / 2.0f;
            mSlideRect.set(mRect.left, mRect.top, mRect.left + mSlideSize, mRect.bottom);
        } else if (ex >= mRect.right - mSlideSize / 2.0f) {
            bitmapX = mBitmap.getWidth() - mSlideSize / 2.0f;
            mSlideRect.set(mRect.right - mSlideSize, mRect.top, mRect.right, mRect.bottom);
        } else {
            bitmapX = ex;
            mSlideRect.set(ex - mSlideSize / 2.0f, mRect.top, ex + mSlideSize / 2.0f, mRect.bottom);
        }
        bitmapY = mRect.top + (mRect.bottom - mRect.top) / 2;

        int pixel = mBitmap.getPixel((int) bitmapX, (int) bitmapY);
        int a = Color.alpha(pixel);
        int r = Color.red(pixel);
        int g = Color.green(pixel);
        int b = Color.blue(pixel);
        int currentColor = Color.argb(a, r, g, b);

        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
            if (mOnColorPickerChangeListener != null) {
                mOnColorPickerChangeListener.onColorChanged(this, currentColor);
                mOnColorPickerChangeListener.onStartTrackingTouch(this);
            }

        } else if (event.getActionMasked() == MotionEvent.ACTION_UP) {
            if (mOnColorPickerChangeListener != null) {
                mOnColorPickerChangeListener.onColorChanged(this, currentColor);
                mOnColorPickerChangeListener.onStopTrackingTouch(this);
            }
        } else {
            if (mOnColorPickerChangeListener != null) {
                mOnColorPickerChangeListener.onColorChanged(this, currentColor);
            }
        }

        invalidate();
        return true;
    }

    private OnColorPickerChangeListener mOnColorPickerChangeListener;

    public void setOnColorPickerChangeListener(OnColorPickerChangeListener l) {
        this.mOnColorPickerChangeListener = l;
    }

    public interface OnColorPickerChangeListener {
        void onColorChanged(ColorPickerView picker, int color);

        void onStartTrackingTouch(ColorPickerView picker);

        void onStopTrackingTouch(ColorPickerView picker);
    }

    public void setSliderResource(int slideResId) {
        this.mSlideResId = slideResId;
        invalidate();
    }

    public void setColors(int... colors) {
        this.mColors = colors;
        invalidate();
    }
}

布局使用:

<ColorPickerView
    android:id="@+id/colorPickerView"
    android:layout_width="match_parent"
    android:layout_height="@dimen/dimen_30"
    android:layout_centerVertical="true"
    app:indicatorSrc="@drawable/img_carsetting_ambient_light_slider_bar"
    app:rx="@dimen/dimen_4"
    app:ry="@dimen/dimen_4" />

代码使用:

mRoot = view.findViewById(R.id.root);
mColorPickerView = view.findViewById(R.id.colorPickerView);
mColorPickerView.setSliderResource(R.drawable.radio_checked);
mColorPickerView.setColors(new int[]{Color.RED, Color.GREEN, Color.BLUE});
mColorPickerView.setOnColorPickerChangeListener(new ColorPickerView.OnColorPickerChangeListener() {
    @Override
    public void onColorChanged(ColorPickerView picker, int color) {
        mRoot.setBackgroundColor(color);
    }

    @Override
    public void onStartTrackingTouch(ColorPickerView picker) {
        Log.e(TAG, "onStartTrackingTouch: ");
    }

    @Override
    public void onStopTrackingTouch(ColorPickerView picker) {
        Log.e(TAG, "onStopTrackingTouch: ");
        mRoot.setBackgroundColor(Color.BLACK);
    }
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值