溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么在Android中通過自定義控件實(shí)現(xiàn)顏色選擇器

發(fā)布時(shí)間:2021-05-14 17:38:52 來源:億速云 閱讀:139 作者:Leah 欄目:移動(dòng)開發(fā)

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)碛嘘P(guān)怎么在Android中通過自定義控件實(shí)現(xiàn)顏色選擇器,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

activity_mian.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<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">

 <TextView
 android:id="@+id/tv_info"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_above="@+id/ll_color"
 android:layout_centerHorizontal="true"
 android:layout_marginBottom="20dp"
 android:gravity="center_horizontal"
 android:text="顏色取值" />

 <LinearLayout
 android:id="@+id/ll_color"
 android:layout_width="match_parent"
 android:layout_height="300dp"
 android:layout_centerInParent="true"
 android:gravity="center"
 android:orientation="vertical"></LinearLayout>
</RelativeLayout>

MainActivity.java文件

package zxz.colorpickerdemo;

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

import zxz.colorpickerdemo.view.ColorPickerView;

public class MainActivity extends AppCompatActivity {

 private LinearLayout ll;
 private TextView tv;
 private ColorPickerView colorPickerView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 ll = (LinearLayout) findViewById(R.id.ll_color);
 tv = (TextView) findViewById(R.id.tv_info);

 colorPickerView = new ColorPickerView(this);
 ll.addView(colorPickerView);
 colorPickerView.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" + colorPickerView.getStrColor());
  tv.setTextColor(Color.argb(a, r, g, b));
  }
 });
 }
}

可以發(fā)現(xiàn),這里自定義控件并沒有直接在布局文件使用,原因是因?yàn)樾枰脩舾鶕?jù)不同的需求通過自定義控件的構(gòu)造函數(shù)傳遞給控件,所以通過ViewGroup.add()將ColorPickerView添加進(jìn)去!

ColorPickerView colorPickerView = new ColorPickerView(context);
 ll.addView(colorPickerView);

-核心部分

就是ColorPickerView的實(shí)現(xiàn)代碼

package zxz.colorpickerdemo.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.view.MotionEvent;
import android.view.View;

public class ColorPickerView extends View {
 private static final float PI = (float) Math.PI;

 private Paint paintCirclePhantom;
 private Paint paintCircle;
 private Paint paintCenterShadow;
 private Paint paintCenter;
 private Paint paintGrayShadow;
 private Paint paintGray;
 private Paint paintLightShadow;
 private Paint paintLight;
 private double Zoom;
 private int[] arrColorGray;
 private final int[] arrColorCircle = new int[]{0xFFFF0000, 0xFFFF00FF,
  0xFF0000FF, 0xFF00FFFF, 0xFF00FF00, 0xFFFFFF00, 0xFFFF0000};
 private boolean mRedrawHSV;
 private boolean IsPressCenter;
 private boolean IsMoveCenter;

 private int CenterX = 100;
 private int CenterY = 100;
 private int CenterRadius = 30;
 private String strColor = "";

 private OnColorBackListener l;

 public ColorPickerView(Context context) {
 super(context);
 float density = getContext().getResources().getDisplayMetrics().density;
 double Zoom = (double) (density / 2.0 + 0.5);
 int color = Color.parseColor("#FFFFFF");
 init(color, Zoom);
 }

 public ColorPickerView(Context context, int color, double Zoom) {
 super(context);
 init(color, Zoom);
 }

 private void init(int color, double Zoom) {
 this.Zoom = Zoom;
 CenterX = (int) (100 * Zoom);
 CenterY = (int) (100 * Zoom);
 CenterRadius = (int) (30 * Zoom);
 paintCirclePhantom = new Paint(Paint.ANTI_ALIAS_FLAG);
 paintCircle = new Paint(Paint.ANTI_ALIAS_FLAG);
 paintCenterShadow = new Paint(Paint.ANTI_ALIAS_FLAG);
 paintCenter = new Paint(Paint.ANTI_ALIAS_FLAG);
 paintGrayShadow = new Paint(Paint.ANTI_ALIAS_FLAG);
 paintGray = new Paint(Paint.ANTI_ALIAS_FLAG);
 paintLightShadow = new Paint(Paint.ANTI_ALIAS_FLAG);
 paintLight = new Paint(Paint.ANTI_ALIAS_FLAG);
 paintCirclePhantom.setColor(0xFF000000);
 paintCirclePhantom.setStyle(Paint.Style.STROKE);
 paintCirclePhantom.setStrokeWidth((float) (32 * Zoom));

 paintCircle.setShader(new SweepGradient(0, 0, arrColorCircle, null));
 paintCircle.setStyle(Paint.Style.STROKE);
 paintCircle.setStrokeWidth((float) (32 * Zoom));

 paintCenterShadow.setColor(0xFF000000);
 paintCenterShadow.setStrokeWidth((float) (5 * Zoom));

 paintCenter.setColor(color);
 paintCenter.setStrokeWidth((float) (5 * Zoom));

 paintGrayShadow.setColor(0xFF000000);
 paintGrayShadow.setStrokeWidth((float) (30 * Zoom));

 arrColorGray = new int[]{0xFFFFFFFF, color, 0xFF000000};
 paintGray.setStrokeWidth((float) (30 * Zoom));

 paintLightShadow.setColor(0xFF000000);
 paintLightShadow.setStrokeWidth((float) (60 * Zoom));

 paintLight.setStrokeWidth((float) (60 * Zoom));

 mRedrawHSV = true;
 }

 @Override
 protected void onDraw(Canvas canvas) {
 canvas.translate(CenterX, CenterY);
 float r = CenterX - paintCircle.getStrokeWidth() * 0.5f; 
 int color = paintCenter.getColor();
 strColor = "#" + Integer.toHexString(color).substring(2).toUpperCase();

 if (mRedrawHSV) {
  arrColorGray[1] = color;
  paintGray.setShader(new LinearGradient(CenterX, -CenterY, CenterX,
   (float) (100 * Zoom), arrColorGray, null,
   Shader.TileMode.CLAMP));
 }

 canvas.drawOval(new RectF(-r + 3, -r + 3, r + 3, r + 3),
  paintCirclePhantom);
 canvas.drawOval(new RectF(-r, -r, r, r), paintCircle);
 canvas.drawCircle(3, 3, CenterRadius, paintCenterShadow);
 canvas.drawCircle(0, 0, CenterRadius, paintCenter);
 canvas.drawRect(new RectF(CenterX + (float) (18 * Zoom), -CenterY + 3,
   CenterX + (float) (48 * Zoom), (float) (103 * Zoom)),
  paintGrayShadow);
 canvas.drawRect(new RectF(CenterX + (float) (15 * Zoom), -CenterY,
  CenterX + (float) (45 * Zoom), (float) (100 * Zoom)), paintGray); 

 if (IsPressCenter) {
  paintCenter.setStyle(Paint.Style.STROKE);

  if (IsMoveCenter)
  paintCenter.setAlpha(0xFF);
  else
  paintCenter.setAlpha(0x66);

  canvas.drawCircle(0, 0,
   CenterRadius + paintCenter.getStrokeWidth(), paintCenter);
  paintCenter.setStyle(Paint.Style.FILL);
  paintCenter.setColor(color);
 }

 mRedrawHSV = true;
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 setMeasuredDimension(CenterX * 2 + 50, CenterY * 2 + 23);
 }

 private int ave(int s, int d, float p) {
 return s + java.lang.Math.round(p * (d - s));
 }

 private int interpColor(int colors[], float unit) {
 if (unit <= 0) {
  return colors[0];
 }
 if (unit >= 1) {
  return colors[colors.length - 1];
 }

 float p = unit * (colors.length - 1);
 int i = (int) p;
 p -= i;

 int c0 = colors[i];
 int c1 = colors[i + 1];
 int a = ave(Color.alpha(c0), Color.alpha(c1), p);
 int r = ave(Color.red(c0), Color.red(c1), p);
 int g = ave(Color.green(c0), Color.green(c1), p);
 int b = ave(Color.blue(c0), Color.blue(c1), p);
 if (l != null) {
  l.onColorBack(a, r, g, b);
 }
 return Color.argb(a, r, g, b);
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
 float x = event.getX() - CenterX;
 float y = event.getY() - CenterY;
 boolean inCenter = java.lang.Math.sqrt(x * x + y * y) <= CenterRadius;

 switch (event.getAction()) {
  case MotionEvent.ACTION_DOWN: {
  IsPressCenter = inCenter;
  if (inCenter) {
   IsMoveCenter = true;
   invalidate();
   break;
  }
  }
  case MotionEvent.ACTION_MOVE: {
  if (IsPressCenter) {
   if (IsMoveCenter != inCenter) {
   IsMoveCenter = inCenter;
   invalidate();
   }
  } else if ((x >= -CenterX && x <= CenterX)
   && (y >= -CenterY && y <= CenterY)) {
   float angle = (float) java.lang.Math.atan2(y, x);
   float unit = angle / (2 * PI);
   if (unit < 0)
   unit += 1;
   paintCenter.setColor(interpColor(arrColorCircle, unit));
   invalidate();
  } else {
   int a, r, g, b, c0, c1;
   float p;

   if (y < 0) {
   c0 = arrColorGray[0];
   c1 = arrColorGray[1];
   p = (y + 100) / 100;
   } else {
   c0 = arrColorGray[1];
   c1 = arrColorGray[2];
   p = y / 100;
   }

   a = ave(Color.alpha(c0), Color.alpha(c1), p);
   r = ave(Color.red(c0), Color.red(c1), p);
   g = ave(Color.green(c0), Color.green(c1), p);
   b = ave(Color.blue(c0), Color.blue(c1), p);

   paintCenter.setColor(Color.argb(a, r, g, b));
   mRedrawHSV = false;
   if (l != null) {
   l.onColorBack(a, r, g, b);
   }
   invalidate();
  }
  break;
  }
  case MotionEvent.ACTION_UP: {
  if (IsPressCenter) {
   IsPressCenter = false;
   invalidate();
  }
  break;
  }
 }
 return true;
 }

 public Paint getpaintCirclePhantom() {
 return paintCirclePhantom;
 }

 public void setpaintCirclePhantom(Paint paintCirclePhantom) {
 this.paintCirclePhantom = paintCirclePhantom;
 }

 public Paint getPaintCircle() {
 return paintCircle;
 }

 public void setPaintCircle(Paint paintCircle) {
 this.paintCircle = paintCircle;
 }

 public Paint getPaintCenterShadow() {
 return paintCenterShadow;
 }

 public void setPaintCenterShadow(Paint paintCenterShadow) {
 this.paintCenterShadow = paintCenterShadow;
 }

 public Paint getPaintCenter() {
 return paintCenter;
 }

 public void setPaintCenter(Paint paintCenter) {
 this.paintCenter = paintCenter;
 }

 public Paint getPaintGrayShadow() {
 return paintGrayShadow;
 }

 public void setPaintGrayShadow(Paint paintGrayShadow) {
 this.paintGrayShadow = paintGrayShadow;
 }

 public Paint getPaintGray() {
 return paintGray;
 }

 public void setPaintGray(Paint paintGray) {
 this.paintGray = paintGray;
 }

 public int[] getArrColorGray() {
 return arrColorGray;
 }

 public void setArrColorGray(int[] arrColorGray) {
 this.arrColorGray = arrColorGray;
 }

 public boolean ismRedrawHSV() {
 return mRedrawHSV;
 }

 public void setmRedrawHSV(boolean mRedrawHSV) {
 this.mRedrawHSV = mRedrawHSV;
 }

 public boolean isIsPressCenter() {
 return IsPressCenter;
 }

 public void setIsPressCenter(boolean isPressCenter) {
 IsPressCenter = isPressCenter;
 }

 public boolean isIsMoveCenter() {
 return IsMoveCenter;
 }

 public void setIsMoveCenter(boolean isMoveCenter) {
 IsMoveCenter = isMoveCenter;
 }

 public int[] getArrColorCircle() {
 return arrColorCircle;
 }

 public String getStrColor() {
 return strColor;
 }

 public void setStrColor(String strColor) {
 this.strColor = strColor;
 }

 public double getZoom() {
 return Zoom;
 }

 public void setZoom(double zoom) {
 Zoom = zoom;
 }

 public void setOnColorBackListener(OnColorBackListener l) {
 this.l = l;
 }

 public interface OnColorBackListener {
 public void onColorBack(int a, int r, int g, int b);
 }
}

注意:

1、ColorPickerView重寫了兩個(gè)構(gòu)造方法,第一個(gè)ColorPickerView(context) 這個(gè)方法創(chuàng)建的取色器默認(rèn)繪制的大小比為屏幕密度,默認(rèn)的顏色為白色;第二個(gè)ColorPickerView(context, color, zoom) color為默認(rèn)顏色,zoom為繪制大小比例。

2、調(diào)用colorPickerView的setOnColorBackListener方法監(jiān)聽顏色的變化,回調(diào) a r g b 0~255的值。colorPickerView.getStrColor()獲取rgb對(duì)應(yīng)的十六進(jìn)制值,比如#FF00FF

Android是什么

Android是一種基于Linux內(nèi)核的自由及開放源代碼的操作系統(tǒng),主要使用于移動(dòng)設(shè)備,如智能手機(jī)和平板電腦,由美國Google公司和開放手機(jī)聯(lián)盟領(lǐng)導(dǎo)及開發(fā)。

上述就是小編為大家分享的怎么在Android中通過自定義控件實(shí)現(xiàn)顏色選擇器了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI