先上图,废话下面说:
参考网址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后并把颜色值显示出来。
本人零基础小白一枚,恳请各位前辈多多包涵。