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

Posted Mars-xq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义view:颜色选择器drawBitmap / seekbar相关的知识,希望对你有一定的参考价值。

自定义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);
    
);

以上是关于自定义view:颜色选择器drawBitmap / seekbar的主要内容,如果未能解决你的问题,请参考以下文章

安卓自定义弧形刻度选择器

安卓自定义弧形刻度选择器

一个灵活高度自定义的JavaScript颜色选择器

颜色组合框和自定义颜色选择器

Android自定义View之区块选择器

Android 自定义 View 知识点