Android 圆形调色板

先上图,废话下面说:

Android 圆形调色板_第1张图片

       

参考网址1:https://blog.csdn.net/zhaoshuiruoli/article/details/38896073

参考网址2:https://blog.csdn.net/feiniyan4944/article/details/79036120

参考网址3:https://blog.csdn.net/u010134293/article/details/52813756

       本人android零基础小白一枚,由于项目需求,需要编写一款调试app,内容涉及到了调色板的功能,于是就开始了android从入门到放弃的学习之旅。刚开始的时候,无从下手,于是就从GitHub下载了一堆别人写好的源码。原以为源码在手,一切都好搞。但是当导入工程的时候,一连串的问题就来了,先是版本兼容问题,然后又是各种编译出错。在百度上挣扎了大半天问题搜索后,本人选择放弃治疗。直到最后,发掘了上面三篇简单易懂的好文章,调色板选色功能实现。

       背景圆是用颜色数组画出的一个圆,然后触摸的时候取色,到最后把颜色值设置回去,就实现了上图文字颜色的跟随更改,下面上码:

首先在values下创建attrs.xml文件,然后自定义几个属性:



 
    
 
        
        
        
        
        
        
    
 

       自定义ColorPickView继承View,用来描绘背景圆和滑动小球,然后获取触摸的位置和触摸位置的颜色,最后根据获取的颜色像素值经转换后可以获得对应的argb数据。

package com.example.colorpickertest;

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.ComposeShader;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by Administrator on 2019/10/10.
 */

public class ColorPickView extends View{
    private Context context;
    private int bigCircle;      //外圆半径
    private int rudeRadius;     //可移动小球的半径
    private int centerColor;    //可移动小球的颜色
    private Bitmap bitmapBack;  //背景图片
    private Paint mPaint;       //背景画笔
    private Paint mCenterPaint; //可移动小球背景
    private Point centerPoint;  //中心位置
    private Point mRockPosition;    //小球当前位置
    private OnColorChangedListener listener;    //小球移动监听
    private int length;             //小球到中心位置的距离
    public String colorStr="";

    public ColorPickView(Context context) {
        super(context);
    }

    public ColorPickView(Context context, AttributeSet attrs, int defStyleAttr){
        super(context, attrs, defStyleAttr);
        this.context = context;
        init(attrs);
    }

    public ColorPickView(Context context, AttributeSet attrs){
        super(context,attrs);
        this.context = context;
        init(attrs);
    }

    public void setOnColorChangedListener(OnColorChangedListener listener){
        this.listener = listener;
    }

    /**
     * @describe 初始化操作
     * @param attrs
     */
    private void init(AttributeSet attrs) {
        TypedArray types = context.obtainStyledAttributes(attrs,R.styleable.color_picker);
        try {
            //外圆半径
            bigCircle = types.getDimensionPixelOffset(R.styleable.color_picker_circle_radius,100);
            //可移动小球半径
            rudeRadius = types.getDimensionPixelOffset(R.styleable.color_picker_center_radius,10);
            //可移动小球的颜色
            centerColor =types.getColor(R.styleable.color_picker_center_color, Color.WHITE);
        }finally {
            types.recycle();    //TypeArray用完需要recycle
        }
        
        //中心位置坐标
        centerPoint = new Point(bigCircle,bigCircle);
        mRockPosition = new Point(centerPoint);

        //初始化背景画笔和可移动小球的画笔
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);

        mCenterPaint = new Paint();
        mCenterPaint.setColor(centerColor);

        bitmapBack = createColorBitmap(bigCircle*2,bigCircle*2);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //画背景图
        canvas.drawBitmap(bitmapBack,0,0,null);
        //画中心小球
        canvas.drawCircle(mRockPosition.x,mRockPosition.y,rudeRadius,mCenterPaint);
    }

    private Bitmap createColorBitmap(int width, int height) {
        Bitmap bitmap = Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888);

        int colorCount = 12;
        int colorAngleStep = 360 / 12;
        int colors[] = new int[colorCount + 1];
        float hsv[] = new float[]{0f,1f,1f};
        for(int i=0;i bigCircle - rudeRadius){
                    return true;
                }
                break;

            case MotionEvent.ACTION_MOVE:       //移动
                length = getLength(event.getX(),event.getY(),centerPoint.x,centerPoint.y);
                if(length <= bigCircle - rudeRadius){
                    mRockPosition.set((int) event.getX(),(int) event.getY());
                }else{
                    mRockPosition = getBorderPoint(centerPoint,new Point((int) event.getX(),(int) event.getY()),bigCircle - rudeRadius);
                }
                //listener.onColorChange(bitmapBack.getPixel(mRockPosition.x,mRockPosition.y));
                break;

            case MotionEvent.ACTION_UP:         //抬起
                break;

            default:
                break;
        }
        getRGB();
        invalidate();               //更新画布
        return true;
    }

    /*
    *转16进制数
     */
    private String toBrowserHexValue(int number){
        StringBuilder builder = new StringBuilder(Integer.toHexString(number &0xff));
        while (builder.length() < 2){
            builder.append("0");
        }
        return builder.toString().toUpperCase();
    }

    /*
    *像素转RGB
     */
    private void getRGB() {
        int pixel = bitmapBack.getPixel((int)mRockPosition.x,(int)mRockPosition.y);
        int r = Color.red(pixel);
        int g = Color.green(pixel);
        int b = Color.blue(pixel);
        int a = Color.alpha(pixel);

        //十六进制的颜色字符串
        colorStr = "#" + toBrowserHexValue(r) + toBrowserHexValue(g) + toBrowserHexValue(b);
        if(listener != null){
            listener.onColorChange(a,r,g,b);
        }
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //视图大小设置为直径
        setMeasuredDimension(bigCircle*2,bigCircle*2);
    }

    //计算两点之间的位置
    private static int getLength(float x1, float y1, int x2, int y2) {
        return (int) Math.sqrt(Math.pow(x1 - x2,2) + Math.pow(y1 - y2,2));
    }

    //当触摸点超出圆的范围的时候,设置小球边缘位置
    private static Point getBorderPoint(Point a, Point b, int cutRadius) {
        float radian = getRadian(a,b);
        return new Point(a.x + (int) (cutRadius  * Math.cos(radian)),a.x + (int)(cutRadius * Math.sin(radian)));
    }

    //触摸点与中心点之间直线与水平方向的夹角角度
    public static float getRadian(Point a, Point b){
        float lenA = b.x - a.x;
        float lenB = b.y - a.y;
        float lenC = (float) Math.sqrt(lenA * lenA + lenB * lenB);
        float ang = (float) Math.acos(lenA / lenC);
        ang = ang * (b.y < a.y ? -1 : 1);
        return  ang;
    }

    public String getColorStr(){
        return  colorStr;
    }

    public void setColorStr(String colorStr){
        this.colorStr = colorStr;
    }

    //颜色发生变化的回调接口
    public interface OnColorChangedListener {
        void onColorChange(int a, int r, int g, int b);
    }
}

 layout中的界面显示内容:




    

    

最后调用以下场景类进行测试:

package com.example.colorpickertest;

import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private TextView txtColor;
    private ColorPickView myView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myView = (ColorPickView) findViewById(R.id.color_picker_view);
        txtColor = (TextView) findViewById(R.id.txt_color);

        myView.setOnColorChangedListener(new ColorPickView.OnColorChangedListener() {
            @Override
            public void onColorChange(int a, int r, int g, int b) {
                txtColor.setText("R:"+ r + "\nG:" + g + "\nB:" + b +"\n" + myView.getColorStr());
                txtColor.setTextColor(Color.argb(a,r,g,b));
            }
        });
    }
}

本人主要以 https://blog.csdn.net/zhaoshuiruoli/article/details/38896073该博主的博客为基础进行修改,该博主是以图片进行取色的。然后本人参考了https://blog.csdn.net/u010134293/article/details/52813756这位博主的博客,用数组画出一个背景圆,然后再取色。最后参考了https://blog.csdn.net/feiniyan4944/article/details/79036120这位博主的博客,将获取到当前选择区域的像素转换成rgb后并把颜色值显示出来。

本人零基础小白一枚,恳请各位前辈多多包涵。

 

你可能感兴趣的:(android)