android 调色盘颜色选取
先来张效果图
主要是继承View的类,通过Paint的画笔类,对小圆点即选择的位置做区域限制,获取到当前选择区域的像素转换成rgb。
核心类ColorPickerView
public class ColorPickerView extends View { private Context mContext; private Paint mRightPaint; //画笔 private int mHeight; //view高 private int mWidth; //view宽 private Bitmap mLeftBitmap; private Bitmap bitmapTemp; private Paint mBitmapPaint;//画笔 private PointF mLeftSelectPoint;//坐标 private OnColorBackListener onColorBackListener; private int mLeftBitmapRadius; public String colorStr=""; private int initX = 0; private int initY = 0; private int r;//半径 public ColorPickerView(Context context) { this(context, null); } public ColorPickerView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; init(); } public void setOnColorBackListener(OnColorBackListener listener) { onColorBackListener = listener; } //初始化资源与画笔 private void init() { bitmapTemp = BitmapFactory.decodeResource(getResources(), R.drawable.color_wheel); mRightPaint = new Paint(); mRightPaint.setStyle(Paint.Style.FILL); mRightPaint.setStrokeWidth(1); mBitmapPaint = new Paint(); mLeftBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.color_wheel_dot); mLeftBitmapRadius = mLeftBitmap.getWidth() / 2; //获取圆心 initX = bitmapTemp.getWidth() / 2; initY = bitmapTemp.getHeight() / 2; r = bitmapTemp.getHeight() / 2; mLeftSelectPoint = new PointF(0, 0); } //important patient please!!! @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(bitmapTemp , null , new Rect(0, 0, mWidth , mHeight ), mBitmapPaint); if(mLeftSelectPoint.x != 0 || mLeftSelectPoint.y != 0){ canvas.drawBitmap(mLeftBitmap, mLeftSelectPoint.x - mLeftBitmapRadius, mLeftSelectPoint.y - mLeftBitmapRadius, mBitmapPaint); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { mWidth = bitmapTemp.getWidth(); mHeight = bitmapTemp.getHeight(); setMeasuredDimension(mWidth, mHeight); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: proofLeft(x, y); invalidate(); getRGB(); break; case MotionEvent.ACTION_UP: //取色 getRGB(); invalidate(); } return true; } 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 = bitmapTemp.getPixel((int)mLeftSelectPoint.x, (int)mLeftSelectPoint.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 (onColorBackListener != null) { onColorBackListener.onColorBack(a, r, g, b); } } /** * 当view离开附着的窗口时触发,该方法和 onAttachedToWindow() 是相反 */ @Override protected void onDetachedFromWindow() { if (mLeftBitmap != null && mLeftBitmap.isRecycled() == false) { mLeftBitmap.recycle();//图片回收 } if (bitmapTemp != null && bitmapTemp.isRecycled() == false) { bitmapTemp.recycle();//图片回收 } super.onDetachedFromWindow(); } // 校正xy private void proofLeft(float x, float y) { int r = bitmapTemp.getWidth() / 2 - mLeftBitmapRadius / 2;//圆半径 //北 PointF N = new PointF(initX,initY - r);//北 PointF S = new PointF(initX,initY + r);//南 PointF W = new PointF(initX - r,initY);//西 PointF E = new PointF(initX + r,initY);//东 int a = twoSpotGetLine(initX,initY,x,y);//圆心到点 if(a < r){//在圆内 mLeftSelectPoint.x = x; mLeftSelectPoint.y = y; }else{ double angle = 0; int c = r; int b = 0; int newx = 0; int newy = 0; if(x > initX){//二四象限 NE SE if(y > initY){//四象限 东南ES b = twoSpotGetLine(S.x,S.y,x,y);//南点到点 double aoccos = (Math.pow(a,2)+ Math.pow(c,2) - Math.pow(b,2)) / (2*a*c); angle = 90d - (Math.acos(aoccos)*(180/Math.PI));//角度 Log.e("getLeftColor", "角度东南ES a: " + a + ",b: " + b + ",c: " + c + ",angle:" + angle); if(angle % 90 == 0){ newx = initX; newy = initY + r; } }else if(y < initY){//二象限 北东EN b = twoSpotGetLine(E.x,E.y,x,y);//北点到点 double aoccos = (Math.pow(a,2)+ Math.pow(c,2) - Math.pow(b,2)) / (2*a*c); angle = 360d - (Math.acos(aoccos)*(180/Math.PI));//角度 Log.e("getLeftColor", "角度北东EN a: " + a + ",b: " + b + ",c: " + c + ",angle:" + angle); if(angle % 90 == 0){ newx = initX + r; newy = initY; } } }else{//一三象限 if(y > initY){//一象限 西北WN b = twoSpotGetLine(W.x,W.y,x,y);//西点到点 double aoccos = (Math.pow(a,2)+ Math.pow(c,2) - Math.pow(b,2)) / (2*a*c); angle = 180d - (Math.acos(aoccos)*(180/Math.PI));//角度 Log.e("getLeftColor", "角度西北WN a: " + a + ",b: " + b + ",c: " + c + ",angle:" + angle); if(angle % 90 == 0){ newx = initX - r; newy = initY; } }else if(y < initY){//三象限 南西SW b = twoSpotGetLine(N.x,N.y,x,y);//东点到点 double aoccos = (Math.pow(a,2)+ Math.pow(c,2) - Math.pow(b,2)) / (2*a*c); angle = 270d - (Math.acos(aoccos)*(180/Math.PI));//角度 Log.e("getLeftColor", "角度南西SW a: " + a + ",b: " + b + ",c: " + c + ",angle:" + angle); if(angle % 90 == 0){ newx = initX; newy = initY - r; } } } if(angle % 90 != 0){ newx = (int)(initX + r * Math.cos(angle * Math.PI/180)); newy = (int)(initY + r * Math.sin(angle * Math.PI/180)); } Log.e("getLeftColor", "新坐标 x: " + newx + ",y: " + newy ); mLeftSelectPoint.x = newx; mLeftSelectPoint.y = newy; } // 图片区域 // if (x < 0) { // mLeftSelectPoint.x = 0; // } else if (x > (LEFT_WIDTH)) { // mLeftSelectPoint.x = LEFT_WIDTH; // } else { // mLeftSelectPoint.x = x; // } // // Log.e("proofLeft()", "proofLeft: " + x + "," + y); // if (x < 0) { // mLeftSelectPoint.x = 0; // } else if (x > (LEFT_WIDTH)) { // mLeftSelectPoint.x = LEFT_WIDTH; // } else { // mLeftSelectPoint.x = x; // } // if (y < 0) { // mLeftSelectPoint.y = 0; // } else if (y > (mHeight - 0)) { // mLeftSelectPoint.y = mHeight - 0; // } else { // mLeftSelectPoint.y = y; // } } /** * 两点取直线 * @param x1 * @param y1 * @param x2 * @param y2 * @return */ private int twoSpotGetLine(float x1,float y1,float x2,float y2){ double line2 = Math.pow((x1-x2),2) + Math.pow((y1-y2),2); return (int)Math.abs(Math.sqrt(line2)); } public String getColorStr() { return colorStr; } public void setColorStr(String colorStr) { this.colorStr = colorStr; } public interface OnColorBackListener { public void onColorBack(int a, int r, int g, int b); } }首页 MainActivity
public class MainActivity extends Activity { private ColorPickerView colorDisk=null; private TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv=(TextView)findViewById(R.id.tv_info); colorDisk=(ColorPickerView)findViewById(R.id.colorDisk); colorDisk.setOnColorBackListener(new ColorPickerView.OnColorBackListener() { @Override public void onColorBack(int a, int r, int g, int b) { tv.setText("R:" + r + "\nG:" + g + "\nB:" + b + "\n" + colorDisk.getColorStr()); tv.setTextColor(Color.argb(a, r, g, b)); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } }xml页面
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <com.mrlin.mycolordisk.ColorPickerView android:id="@+id/colorDisk" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true"/> <TextView android:id="@+id/tv_info" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/colorDisk" android:layout_centerHorizontal="true" android:layout_marginBottom="20dp" android:gravity="center_horizontal" android:layout_marginTop="15dp" android:text="颜色取值" /> </RelativeLayout>
最后附上源码
http://download.****.net/download/feiniyan4944/10200855