中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在android中通過自定義View實現一個圓環顏色選擇器

發布時間:2021-05-14 17:36:10 來源:億速云 閱讀:179 作者:Leah 欄目:移動開發

這篇文章給大家介紹怎么在android中通過自定義View實現一個圓環顏色選擇器,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

public class MyColorPicker extends View {

 private int mThumbHeight;
 private int mThumbWidth;
 private String[] colors ;

 private int sections;
 //每個小塊的度數
 private int sectionAngle;

 private Paint mPaint;

 private int ringWidth;

 private RectF mRectF;

 private Drawable mThumbDrawable = null;
 private float mThumbLeft;
 private float mThumbTop;
 private double mViewCenterX, mViewCenterY;
 private double mViewRadisu;
 //起始角度
 private int mStartDegree = -90;

 //當前view的尺寸
 private int mViewSize;

 private int textColor;
 private String text="";

 private Paint textPaint;

 private Rect mBounds;

 private float textSize;

 private int colorType;

 private int default_size = 100;

 public MyColorPicker(Context context) {
  this(context, null);
 }

 public MyColorPicker(Context context, AttributeSet attrs) {
  this(context, attrs, 0);
 }

 public MyColorPicker(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  TypedArray localTypedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleColorPicker);
  mThumbDrawable = localTypedArray.getDrawable(R.styleable.CircleColorPicker_thumb);
  ringWidth = (int) localTypedArray.getDimension(R.styleable.CircleColorPicker_ring_span, 30);
  colorType = localTypedArray.getInt(R.styleable.CircleColorPicker_color_type, 0);
  textColor = localTypedArray.getColor(R.styleable.CircleColorPicker_text_color, Color.BLACK);
  text = localTypedArray.getString(R.styleable.CircleColorPicker_text);
  textSize = localTypedArray.getDimension(R.styleable.CircleColorPicker_text_size, 20);
  localTypedArray.recycle();
  default_size = SystemUtils.dip2px(context, 260);
  init();
 }

 private void init() {

  colors = colorType == 1 ? ColorUtils.getMacaroon():ColorUtils.getAllColors();
  sections = colors.length;
  mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  mPaint.setStyle(Paint.Style.STROKE);
  mPaint.setStrokeWidth(ringWidth);

  textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  textPaint.setColor(textColor);
  textPaint.setTextSize(textSize);
  mThumbWidth = this.mThumbDrawable.getIntrinsicWidth();
  mThumbHeight = this.mThumbDrawable.getIntrinsicHeight();

  sectionAngle = 360/sections;

  mBounds = new Rect();

 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  setMeasuredDimension(getMeasuredLength(widthMeasureSpec, true), getMeasuredLength(heightMeasureSpec, false));

  int circleX = getMeasuredWidth();
  int circleY = getMeasuredHeight();
  if (circleY < circleX)
  {
   circleX = circleY;
  }
  mViewSize = circleX;
  mViewCenterX = circleX/2;
  mViewCenterY = circleY/2;
  mViewRadisu = circleX/2 - mThumbWidth / 2;

  setThumbPosition(Math.toRadians(mStartDegree));
 }

 private int getMeasuredLength(int length, boolean isWidth) {
  int specMode = MeasureSpec.getMode(length);
  int specSize = MeasureSpec.getSize(length);
  int size;
  int padding = isWidth ? getPaddingLeft() + getPaddingRight() : getPaddingTop() + getPaddingBottom();
  if (specMode == MeasureSpec.EXACTLY) {
   size = specSize;
  } else {
   size = default_size + padding;
   if (specMode == MeasureSpec.AT_MOST) {
    size = Math.min(size, specSize);
   }
  }
  return size;
 }

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);

  mRectF = new RectF(0+mThumbWidth/2, 0+mThumbWidth/2, mViewSize-mThumbWidth/2, mViewSize-mThumbWidth/2);

  for (int i = 0; i < colors.length; i++)
  {
   mPaint.setColor(Color.parseColor(colors[i]));
   canvas.drawArc(mRectF, i*sectionAngle-90, sectionAngle+1,false, mPaint);
  }

  mThumbDrawable.setBounds((int) mThumbLeft, (int) mThumbTop,
    (int) (mThumbLeft + mThumbWidth), (int) (mThumbTop + mThumbHeight));
  mThumbDrawable.draw(canvas);

  textPaint.getTextBounds(text, 0, text.length(), mBounds);
  float textWidth = mBounds.width();
  float textHeight = mBounds.height();

  float textLeft = (float) (mViewCenterX - textWidth/2);
  float textTop = (float)(mViewCenterY + textHeight/2);
  canvas.drawText(text, 0, text.length(), textLeft, textTop, textPaint);

 }

 private void setThumbPosition(double radian) {
  double x = mViewCenterX + mViewRadisu * Math.cos(radian);
  double y = mViewCenterY + mViewRadisu * Math.sin(radian);
  mThumbLeft = (float) (x - mThumbWidth / 2);
  mThumbTop = (float) (y - mThumbHeight / 2);
 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  float eventX = event.getX();
  float eventY = event.getY();
  switch (event.getAction()) {
   case MotionEvent.ACTION_DOWN:
    seekTo(eventX, eventY, false);
    break ;

   case MotionEvent.ACTION_MOVE:
    seekTo(eventX, eventY, false);
    break ;

   case MotionEvent.ACTION_UP:
//    seekTo(eventX, eventY, true);
    float part = sectionAngle / 4.0f;
    for (int i = 0; i < sections; i++) {
     if ( mSweepDegree > (i-1)*sectionAngle+part*3 && mSweepDegree < i *sectionAngle + part)
     {
      if (mSweepDegree < i*sectionAngle)
      {
       setThumbPosition(Math.toRadians((i-1)*sectionAngle+part*2));
      }else {
       setThumbPosition(Math.toRadians(i*sectionAngle+part*2));
      }
     }
    }
    if (mSweepDegree > ((sections-1)*sectionAngle)+part*3)
    {
     setThumbPosition(Math.toRadians((sections-1)*sectionAngle+part*2));
    }
    invalidate();
    break ;
  }
  return true;
 }

 private int preColor;

 private float mSweepDegree;
 private void seekTo(float eventX, float eventY, boolean isUp) {
  if (true == isPointOnThumb(eventX, eventY) && false == isUp) {
//   mThumbDrawable.setState(mThumbPressed);

   double radian = Math.atan2(eventY - mViewCenterY, eventX - mViewCenterX);
   /*
    * 由于atan2返回的值為[-pi,pi]
    * 因此需要將弧度值轉換一下,使得區間為[0,2*pi]
    */
   if (radian < 0){
    radian = radian + 2*Math.PI;
   }
   setThumbPosition(radian);

   mSweepDegree = (float) Math.round(Math.toDegrees(radian));

   int currentColor = getColor(mSweepDegree);
   if (currentColor != preColor)
   {
    preColor = currentColor;
    if (onColorChangeListener != null)
    {
     onColorChangeListener.colorChange(preColor);
    }
   }

   invalidate();
  }else{
//   mThumbDrawable.setState(mThumbNormal);
   invalidate();
  }
 }

 private int getColor(float mSweepDegree) {

  int tempIndex = (int) (mSweepDegree/sectionAngle);

  int num = 90 / sectionAngle;

  if (tempIndex ==sections)
  {
   tempIndex = 0;
  }

  int index = tempIndex;
  if (tempIndex >= 0) {
   index = tempIndex+num;
  }
  if (tempIndex >= (sections-num))
  {
   index = tempIndex-(sections-num);
  }

  return Color.parseColor(colors[index]);
 }


 private boolean isPointOnThumb(float eventX, float eventY) {
  boolean result = false;
  double distance = Math.sqrt(Math.pow(eventX - mViewCenterX, 2)
    + Math.pow(eventY - mViewCenterY, 2));
  if (distance < mViewSize && distance > (mViewSize / 2 - mThumbWidth)){
   result = true;
  }
  return result;
 }


 public int getCurrentColor()
 {
  return preColor;
 }

 public void setStartColor(String color)
 {
  for (int i = 0; i < colors.length; i++)
  {
   if (colors[i].equals(color))
   {
    preColor = Color.parseColor(colors[i]);
    int sweepAngle = (i- 90 /sectionAngle)*sectionAngle+sectionAngle/2;
//    postDelayed(()->{
//     setThumbPosition(Math.toRadians(sweepAngle));
//     invalidate();
//    },200);
    mStartDegree = sweepAngle;
    //最好加上
    invalidate();
    break;
   }
  }
 }

 public void setColor(String color) {
  for (int i = 0; i < colors.length; i++)
  {
   if (colors[i].equals(color))
   {
    preColor = Color.parseColor(colors[i]);
    int sweepAngle = (i- 90 /sectionAngle)*sectionAngle+sectionAngle/2;
    setThumbPosition(Math.toRadians(sweepAngle));
    invalidate();
    break;
   }
  }
 }


 public interface OnColorChangeListener
 {
  void colorChange(int color);
 }

 public void setOnColorChangeListener(OnColorChangeListener onColorChangeListener) {
  this.onColorChangeListener = onColorChangeListener;
 }

 private OnColorChangeListener onColorChangeListener;
}

注意的幾個地方:

1. 可滑動位置的判斷以及如何求滑動的角度,這里還去腦補了下atan2這個三角函數
2. 設置指示器的開始的位置,外部調用setStartColor()方法時,這個View可能還沒真正完成繪制。如果沒有完成繪制,第幾行的invalidate()方法其實是沒多大作用。

上面是選擇單個顏色,下面來個加強版,選擇的是顏色區間,先上效果圖:

怎么在android中通過自定義View實現一個圓環顏色選擇器

區間可以自己選擇,并且可以反轉(低指示器在高指示器順時針方向或逆時針方向)。

下面是代碼:

public class IntervalColorPicker extends View {
 private int mThumbHeight;
 private int mThumbWidth;

 private int mThumbLowHeight, mThumbLowWidth;
 private String[] colors = ColorUtils.getAllColors();

 private int sections;
 //每個小塊的度數
 private int sectionAngle;

 private Paint mPaint;

 private Paint arcPaint;

 private int ringWidth;

 private RectF mRectF;

 private Drawable mThumbHighDrawable = null;
 private Drawable mThumbLowDrawable;
 private float mThumbLeft;
 private float mThumbTop;

 private float mThumbLowLeft, mThumbLowTop;

 private double mViewCenterX, mViewCenterY;
 private double mViewRadisu;
 //起始角度
 private float mStartDegree = 270;

 //當前view的尺寸
 private int mViewSize;

 //區間
 private int interval = 7;

 private boolean reverse;

 private float tempStartAngle = mStartDegree;

 public IntervalColorPicker(Context context) {
  this(context, null);
 }

 public IntervalColorPicker(Context context, AttributeSet attrs) {
  this(context, attrs, 0);
 }

 public IntervalColorPicker(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  TypedArray localTypedArray = context.obtainStyledAttributes(attrs, R.styleable.IntervalColorPicker);
  mThumbHighDrawable = localTypedArray.getDrawable(R.styleable.IntervalColorPicker_thumbHigh);
  mThumbLowDrawable = localTypedArray.getDrawable(R.styleable.IntervalColorPicker_thumbLow);
  ringWidth = (int) localTypedArray.getDimension(R.styleable.IntervalColorPicker_ring_breadth, 30);
  localTypedArray.recycle();
  init();
 }

 private void init() {
  sections = colors.length;
  mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  mPaint.setStyle(Paint.Style.STROKE);
  mPaint.setStrokeWidth(ringWidth);

  arcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  arcPaint.setStyle(Paint.Style.STROKE);
  arcPaint.setStrokeWidth(ringWidth + 1);
  arcPaint.setColor(Color.GRAY);

  mThumbWidth = this.mThumbHighDrawable.getIntrinsicWidth();
  mThumbHeight = this.mThumbHighDrawable.getIntrinsicHeight();
  mThumbLowHeight = mThumbLowDrawable.getIntrinsicHeight();
  mThumbLowWidth = mThumbHighDrawable.getIntrinsicWidth();

  sectionAngle = 360 / sections;
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  int circleX = getMeasuredWidth();
  int circleY = getMeasuredHeight();
  if (circleY < circleX) {
   circleX = circleY;
  }
  mViewSize = circleX;
  mViewCenterX = circleX / 2;
  mViewCenterY = circleY / 2;
  mViewRadisu = circleX / 2 - mThumbWidth / 2;
 }

 private float sweepAngle;

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);

  mRectF = new RectF(0 + mThumbWidth / 2, 0 + mThumbWidth / 2, mViewSize - mThumbWidth / 2, mViewSize - mThumbWidth / 2);

  for (int i = 0; i < colors.length; i++) {
   mPaint.setColor(Color.parseColor(colors[i]));
   canvas.drawArc(mRectF, i * sectionAngle - 90, sectionAngle + 1, false, mPaint);
  }

  int tempAng = (int) (tempStartAngle + sweepAngle);
  int intervalAngle = interval * sectionAngle;

  if (reverse) {
   setThumbPosition(Math.toRadians(tempAng));
   setThumbLowPosition(Math.toRadians(tempAng - intervalAngle));
   canvas.drawArc(mRectF, tempAng, 360 - intervalAngle, false, arcPaint);
  } else {
   setThumbPosition(Math.toRadians(tempAng));
   setThumbLowPosition(Math.toRadians(tempAng + intervalAngle));
   canvas.drawArc(mRectF, (int) (tempAng + intervalAngle), 360 - intervalAngle, false, arcPaint);
  }

  mThumbHighDrawable.setBounds((int) mThumbLeft, (int) mThumbTop,
    (int) (mThumbLeft + mThumbWidth), (int) (mThumbTop + mThumbHeight));
  mThumbLowDrawable.setBounds((int) mThumbLowLeft, (int) mThumbLowTop, (int) (mThumbLowLeft + mThumbLowWidth), (int) (mThumbLowTop + mThumbLowHeight));


  mThumbHighDrawable.draw(canvas);
  mThumbLowDrawable.draw(canvas);
 }

 private void setThumbPosition(double radian) {
  double x = mViewCenterX + mViewRadisu * Math.cos(radian);
  double y = mViewCenterY + mViewRadisu * Math.sin(radian);
  mThumbLeft = (float) (x - mThumbWidth / 2);
  mThumbTop = (float) (y - mThumbHeight / 2);
 }

 private void setThumbLowPosition(double radian) {
  double x = mViewCenterX + mViewRadisu * Math.cos(radian);
  double y = mViewCenterY + mViewRadisu * Math.sin(radian);
  mThumbLowLeft = (float) (x - mThumbLowWidth / 2);
  mThumbLowTop = (float) (y - mThumbLowHeight / 2);
 }

 private boolean isDown = true;

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  float eventX = event.getX();
  float eventY = event.getY();
  switch (event.getAction()) {
   case MotionEvent.ACTION_DOWN:
    getEventDegree(eventX, eventY);
//    seekTo(eventX, eventY, false);
    break;

   case MotionEvent.ACTION_MOVE:

    seekTo(eventX, eventY);
    break;

   case MotionEvent.ACTION_UP:
    postDelayed(() -> {
     tempStartAngle = tempStartAngle + sweepAngle;
     sweepAngle = 0;
     getSelectedColor();
     if (onColorChangeListener != null) {
      onColorChangeListener.colorChange(selectedColors);
     }

    }, 100);

    break;

  }
  return true;
 }

 private float downDegree;

 private void getEventDegree(float eventX, float eventY) {
  if (isPointOnThumb(eventX, eventY)) {
   double radian = Math.atan2(eventY - mViewCenterY, eventX - mViewCenterX);
   /*
    * 由于atan2返回的值為[-pi,pi]
    * 因此需要將弧度值轉換一下,使得區間為[0,2*pi]
    */
   if (radian < 0) {
    radian = radian + 2 * Math.PI;
   }
   isDown = true;
   downDegree = Math.round(Math.toDegrees(radian));
  } else {
   isDown = false;
  }
 }

 private void seekTo(float eventX, float eventY) {
  if (true == isPointOnThumb(eventX, eventY)) {
//   mThumbHighDrawable.setState(mThumbPressed);

   if (!isDown) {
    getEventDegree(eventX, eventY);
    isDown = true;
   }

   double radian = Math.atan2(eventY - mViewCenterY, eventX - mViewCenterX);
   /*
    * 由于atan2返回的值為[-pi,pi]
    * 因此需要將弧度值轉換一下,使得區間為[0,2*pi]
    */
   if (radian < 0) {
    radian = radian + 2 * Math.PI;
   }
   setThumbPosition(radian);

   float mSweepDegree = (float) Math.round(Math.toDegrees(radian));

   sweepAngle = mSweepDegree - downDegree;


   invalidate();
  }
 }

 //選中的顏色
 private ArrayList<Integer> selectedColors = new ArrayList<>(interval);

 public void getSelectedColor() {
  int tempIndex = (int) (tempStartAngle / sectionAngle);
  int num = 90 / sectionAngle;
  if (tempIndex == sections) {
   tempIndex = 0;
  }
  int index = tempIndex;
  if (tempIndex >= 0) {
   index = tempIndex + num;
  }
  if (tempIndex >= (sections - num)) {
   index = tempIndex - (sections - num);
  }


  if (index>colors.length)
   index = index%colors.length;
  while (index<0)
  {
   index = colors.length+index;
  }
  selectedColors.clear();
  int startIndex = 0;
  if (reverse)
  {
   startIndex = index - interval -1;
   while (startIndex < 0)
   {
    startIndex = startIndex+colors.length;
   }
   if (startIndex > index)
   {
    for (int i = startIndex+1; i < colors.length; i++) {
     selectedColors.add(Color.parseColor(colors[i]));
    }
    for (int i = 0; i <= index; i++) {
     selectedColors.add(Color.parseColor(colors[i]));
    }
   }else {
    for (int i = startIndex+1; i <= index; i++) {
     selectedColors.add(Color.parseColor(colors[i]));
    }
   }
  }else {
   startIndex = index+interval+1;
   while (startIndex>colors.length)
   {
    startIndex = startIndex-colors.length;
   }
   if (startIndex < index)
   {
    for (int i = startIndex-1; i >= 0; i--) {
     selectedColors.add(Color.parseColor(colors[i]));
    }
    for (int i = colors.length-1; i >= index; i--) {
     selectedColors.add(Color.parseColor(colors[i]));
    }
   }else {
    for (int i = startIndex-1; i >=index; i--) {
     selectedColors.add(Color.parseColor(colors[i]));
    }
   }

  }

 }


 private boolean isPointOnThumb(float eventX, float eventY) {
  boolean result = false;
  double distance = Math.sqrt(Math.pow(eventX - mViewCenterX, 2)
    + Math.pow(eventY - mViewCenterY, 2));
  if (distance < mViewSize && distance > (mViewSize / 2 - mThumbWidth)) {
   result = true;
  }
  return result;
 }


 public boolean isReverse() {
  return reverse;
 }

 public void setReverse(boolean reverse) {
  this.reverse = reverse;
  invalidate();
 }

 public interface OnColorChangeListener {
  void colorChange(ArrayList<Integer> colors);
 }

 public void setOnColorChangeListener(OnColorChangeListener onColorChangeListener) {
  this.onColorChangeListener = onColorChangeListener;
 }

 private OnColorChangeListener onColorChangeListener;
}

Android是什么

Android是一種基于Linux內核的自由及開放源代碼的操作系統,主要使用于移動設備,如智能手機和平板電腦,由美國Google公司和開放手機聯盟領導及開發。

關于怎么在android中通過自定義View實現一個圓環顏色選擇器就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

南陵县| 吕梁市| 清水河县| 武强县| 婺源县| 五华县| 内乡县| 枞阳县| 武冈市| 大连市| 察隅县| 宜兰县| 准格尔旗| 吉林市| 南城县| 江门市| 凤山县| 资讯| 大冶市| 福安市| 三门峡市| 长子县| 景宁| 河源市| 双辽市| 比如县| 江油市| 德惠市| 广汉市| 珲春市| 淮南市| 宜君县| 准格尔旗| 绥宁县| 成都市| 嘉兴市| 河源市| 日喀则市| 行唐县| 乌兰察布市| 镇平县|