Android 사용자 정의 View 원형 진행 막대 구현

10018 단어 Android진도 표
본 논문 의 사례 는 안 드 로 이 드 사용자 정의 View 가 원형 진도 바 를 실현 하 는 구체 적 인 코드 를 공유 하여 여러분 께 참고 하 시기 바 랍 니 다.구체 적 인 내용 은 다음 과 같 습 니 다.
효 과 는 다음 과 같 습 니 다:

주 코드
CircularProgressView.java

public class CircularProgressView extends View {

  private Paint mBackPaint, mProgPaint;  //     
  private RectF mRectF;    //     
  private int[] mColorArray; //      
  private int mProgress;   //     (0-100)
  /**
   *        
   */
  private Paint progressPaint;

  /**
   *       
   */
  private int centerX, centerY;

  /**
   *      
   */
  private int circleRadius;

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

  public CircularProgressView(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, 0);
  }

  public CircularProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    @SuppressLint("Recycle")
    TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircularProgressView);

    //          
    mBackPaint = new Paint();
    mBackPaint.setStyle(Paint.Style.STROKE);  //    ,   
    mBackPaint.setStrokeCap(Paint.Cap.ROUND);  //     
    mBackPaint.setAntiAlias(true);       //      
    mBackPaint.setDither(true);         //     
    mBackPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_backWidth, 5));
    mBackPaint.setColor(typedArray.getColor(R.styleable.CircularProgressView_progbgColor, Color.LTGRAY));

    //          
    mProgPaint = new Paint();
    mProgPaint.setStyle(Paint.Style.STROKE);  //    ,   
    mProgPaint.setStrokeCap(Paint.Cap.ROUND);  //     
    mProgPaint.setAntiAlias(true);       //      
    mProgPaint.setDither(true);         //     
    mProgPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_progWidth, 10));
    mProgPaint.setColor(typedArray.getColor(R.styleable.CircularProgressView_progColor, Color.BLUE));


    //          
    progressPaint = new Paint();
    progressPaint.setStyle(Paint.Style.FILL);  //   
    progressPaint.setStrokeCap(Paint.Cap.ROUND);  //     
    progressPaint.setAntiAlias(true);       //      
    progressPaint.setDither(true);         //     
    progressPaint.setStrokeWidth(typedArray.getDimension(R.styleable.CircularProgressView_progWidth, 10));
    progressPaint.setColor(Color.WHITE);

    //           
    int startColor = typedArray.getColor(R.styleable.CircularProgressView_progStartColor, -1);
    int firstColor = typedArray.getColor(R.styleable.CircularProgressView_progFirstColor, -1);
    if (startColor != -1 && firstColor != -1) mColorArray = new int[]{startColor, firstColor};
    else mColorArray = null;

    //      
    mProgress = typedArray.getInteger(R.styleable.CircularProgressView_progress, 0);
    typedArray.recycle();
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int viewWide = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
    int viewHigh = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
    int mRectLength = (int) ((viewWide > viewHigh ? viewHigh : viewWide) - (mBackPaint.getStrokeWidth() > mProgPaint.getStrokeWidth() ? mBackPaint.getStrokeWidth() : mProgPaint.getStrokeWidth()));
    int mRectL = getPaddingLeft() + (viewWide - mRectLength) / 2;
    int mRectT = getPaddingTop() + (viewHigh - mRectLength) / 2;
    mRectF = new RectF(mRectL, mRectT, mRectL + mRectLength, mRectT + mRectLength);

    centerX = getMeasuredWidth() / 2;
    centerY = getMeasuredHeight() / 2;

    //          
    circleRadius = Math.min(getMeasuredWidth(), getMeasuredHeight()) / 2;
    circleRadius-=8;
    //          
    if (mColorArray != null && mColorArray.length > 1)
      mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR));
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawArc(mRectF, 0, 360, false, mBackPaint);
    canvas.drawArc(mRectF, 270, 360 * mProgress / 100, false, mProgPaint);

    //         
    progressPaint.setStrokeWidth(10);
    progressPaint.setStyle(Paint.Style.FILL);
    float swipe = 360 * mProgress / 100;
    Log.d("=================", swipe + "    mProgress");
    float radians = (float) (((swipe - 90) / 2) / 180 * 2 * Math.PI);
    float endX;
    float endY;

    endX = centerX + circleRadius * (float) Math.cos(radians);
    endY = centerY + circleRadius * (float) Math.sin(radians);

    if (mProgress!=0) {
      canvas.drawCircle(endX, endY, 8, progressPaint);
    }


  }

  /**
   *       
   *
   * @return     (0-100)
   */
  public int getProgress() {
    return mProgress;
  }

  /**
   *       
   *
   * @param progress     (0-100)
   */
  public void setProgress(int progress) {
    this.mProgress = progress;
    invalidate();
  }

  /**
   *       ,       。          0,      
   *
   * @param progress     (0-100)
   * @param animTime     (  )
   */
  public void setProgress(int progress, long animTime) {
    if (animTime <= 0) setProgress(progress);
    else {
      ValueAnimator animator = ValueAnimator.ofInt(mProgress, progress);
      animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
          mProgress = (int) animation.getAnimatedValue();
          invalidate();
        }
      });
      animator.setInterpolator(new OvershootInterpolator());
      animator.setDuration(animTime);
      animator.start();
    }
  }

  /**
   *         
   *
   * @param width       
   */
  public void setBackWidth(int width) {
    mBackPaint.setStrokeWidth(width);
    invalidate();
  }

  /**
   *         
   *
   * @param color       
   */
  public void setBackColor(/*@ColorRes int color*/String color) {
    mBackPaint.setColor(Color.parseColor(color)); //    
    invalidate();
  }

  /**
   *         
   *
   * @param width       
   */
  public void setProgWidth(int width) {
    mProgPaint.setStrokeWidth(width);
    invalidate();
  }

  /**
   *         
   *
   * @param color      
   */
  public void setProgColor(/*@ColorRes int color*/String color) {
    mProgPaint.setColor(Color.parseColor(color)); //    
    mProgPaint.setShader(null);
    invalidate();
  }

  /**
   *         (     )
   *
   * @param startColor         
   * @param firstColor         
   */
  public void setProgColor(@ColorRes int startColor, @ColorRes int firstColor) {
    mColorArray = new int[]{ContextCompat.getColor(getContext(), startColor), ContextCompat.getColor(getContext(), firstColor)};
    mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR));
    invalidate();
  }

  /**
   *         (     )
   *
   * @param colorArray      
   */
  public void setProgColor(@ColorRes int[] colorArray) {
    if (colorArray == null || colorArray.length < 2) return;
    mColorArray = new int[colorArray.length];
    for (int index = 0; index < colorArray.length; index++)
      mColorArray[index] = ContextCompat.getColor(getContext(), colorArray[index]);
    mProgPaint.setShader(new LinearGradient(0, 0, 0, getMeasuredWidth(), mColorArray, null, Shader.TileMode.MIRROR));
    invalidate();
  }
}
attrs.xml

<declare-styleable name="CircularProgressView">
    <attr name="backWidth" format="dimension" />  <!--      -->
    <attr name="progWidth" format="dimension" />  <!--      -->
    <attr name="progbgColor" format="color" />    <!--      -->
    <attr name="progColor" format="color" />    <!--      -->
    <attr name="progStartColor" format="color" />  <!--        -->
    <attr name="progFirstColor" format="color" />  <!--        -->
    <attr name="progress" format="integer" />    <!--    -->
 </declare-styleable>
사용 방법

<com.view.CircularProgressView
  android:layout_width="170dp"
  android:layout_height="170dp"
  android:layout_centerInParent="true"
  android:layout_centerHorizontal="true"
  app:backWidth="5dp"
  app:progWidth="5dp"
  app:progbgColor="#4C5098"
  app:progress="50"
  android:layout_marginTop="500dp"
  />
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기