Android 사용자 정의 View 원호 진행 효과 구현

앞에서 말 했 듯 이 안 드 로 이 드 개발 에서 사용자 정의 View 는 자신 이 원 하 는 효 과 를 실현 하 는 데 필수 적 인 기능 이 되 었 다.물론 사용자 정의 View 도 안 드 로 이 드 개발 에서 비교적 어 려 운 부분 이다.관련 지식 은 Canvas(캔버스),Paint(붓)등 이 있 고 사용자 정의 컨트롤 은 세 가지 로 나 뉜 다.하 나 는 자체 View 를 직접 계승 하고 완전한 사용자 정의 이다.둘째,기 존의 컨트롤 을 바탕 으로 개조 하여 자신 이 원 하 는 효 과 를 얻 는 것 이다.또 하 나 는 조합 컨트롤 을 사용자 정의 하여 기 존 컨트롤 을 자신의 필요 에 따라 조합 하여 실현 하 는 효과 이다.저 는 사용자 정의 View 에 대해 서도 수박 겉 핥 기 식 으로 알 고 있 습 니 다.사용자 정의 View(자체 View 계승)를 배 우 는 과정 을 간단하게 기록 하여 나중에 읽 기 에 편리 합 니 다.
기술 실현
1.ArcView 계승
2.Canvas(캔버스)
3.Paint(화필)
효과 도:QQ 와 유사 한 스텝 효과

1.뷰 계승
(1)3 개의 구조 방법 을 다시 쓴다(새로운 API 의 구조 방법 은 4 개)

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

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

public ArcView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 //init();
}
(2)View 의 OnDraw 를 다시 쓰 는 방법

@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 centerX=getWidth()/2;
 centerY=getHeight()/2;
 //   paint
 initPaint();
 //    
 drawArc(canvas);
 //    
 drawText(canvas);
}
주:여기 paint 초기 화 는 onDraw 방법 에 넣 었 습 니 다.물론 세 개의 매개 변수 가 있 는 구조 방법 에서 초기 화 할 수 있 습 니 다.
2.Paint 초기 화
(1)원호 의 붓 mArcPaint

//   paint
mArcPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
//   
mArcPaint.setAntiAlias(true);
mArcPaint.setColor(Color.parseColor("#666666"));
//     (   0-255)
mArcPaint.setAlpha(100);
//          
mArcPaint.setStrokeJoin(Paint.Join.ROUND);
mArcPaint.setStrokeCap(Paint.Cap.ROUND);
//      
mArcPaint.setStyle(Paint.Style.STROKE);
mArcPaint.setStrokeWidth(dp2px(mStrokeWith));
(2)글자 의 화필 mTextPaint

//     paint
mTextPaint=new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setColor(Color.parseColor("#FF4A40"));
//         
mTextPaint.setTextAlign(Paint.Align.CENTER);
//mTextPaint.setTextSize(getResources().getDimensionPixelSize(R.dimen.dp_12));
mTextPaint.setTextSize(dp2px(25));
3.Canvas 그리 기
(1)원호 의 그리 기

/**
 *     
 * @param canvas
 */
private void drawArc(Canvas canvas) {
 //      
 RectF mRectF=new RectF(mStrokeWith+dp2px(5),mStrokeWith+dp2px(5),getWidth()-mStrokeWith-dp2px(5),getHeight()-mStrokeWith);
 canvas.drawArc(mRectF,startAngle,mAngle,false,mArcPaint);
 //           
 mArcPaint.setColor(Color.parseColor("#FF4A40"));
 //             
 canvas.drawArc(mRectF,startAngle,mIncludedAngle,false,mArcPaint);
}
(2)텍스트 그리 기

/**
 *     
 * @param canvas
 */
private void drawText(Canvas canvas) {
 Rect mRect=new Rect();
 String mValue=String.valueOf(mAnimatorValue);
 //       
 mTextPaint.getTextBounds(mValue,0,mValue.length(),mRect);
 canvas.drawText(String.valueOf(mAnimatorValue),centerX,centerY+mRect.height(),mTextPaint);

 //        
 mTextPaint.setColor(Color.parseColor("#999999"));
 mTextPaint.setTextSize(dp2px(12));
 mTextPaint.getTextBounds(mDes,0,mDes.length(),mRect);
 canvas.drawText(mDes,centerX,centerY+2*mRect.height()+dp2px(10),mTextPaint);

 //     
 String minValue=String.valueOf(mMinValue);
 String maxValue=String.valueOf(mMaxValue);
 mTextPaint.setTextSize(dp2px(18));
 mTextPaint.getTextBounds(minValue,0,minValue.length(),mRect);
 canvas.drawText(minValue, (float) (centerX-0.6*centerX-dp2px(5)), (float) (centerY+0.75*centerY+mRect.height()+dp2px(5)),mTextPaint);
 //     
 mTextPaint.getTextBounds(maxValue,0,maxValue.length(),mRect);
 canvas.drawText(maxValue, (float) (centerX+0.6*centerX+dp2px(5)), (float) (centerY+0.75*centerY+mRect.height()+dp2px(5)),mTextPaint);
}
4.애니메이션 효과 및 데이터 추가
(1)애니메이션 효과

/**
 *             
 *
 * @param startAngle      
 * @param currentAngle        
 * @param currentValue        
 * @param time        
 */
private void setAnimation(float startAngle, float currentAngle,int currentValue, int time) {
 //                
 ValueAnimator progressAnimator = ValueAnimator.ofFloat(startAngle, currentAngle);
 progressAnimator.setDuration(time);
 progressAnimator.setTarget(mIncludedAngle);
 progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
  @Override
  public void onAnimationUpdate(ValueAnimator animation) {
   mIncludedAngle = (float) animation.getAnimatedValue();
   //    ,        
   postInvalidate();
  }
 });
 //      
 progressAnimator.start();

 //         
 ValueAnimator valueAnimator = ValueAnimator.ofInt(mAnimatorValue, currentValue);
 valueAnimator.setDuration(2500);
 valueAnimator.setInterpolator(new LinearInterpolator());
 valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

  @Override
  public void onAnimationUpdate(ValueAnimator valueAnimator) {

   mAnimatorValue = (int) valueAnimator.getAnimatedValue();
   postInvalidate();
  }
 });
 valueAnimator.start();
}
(2)데이터 추가

/**
 *     
 * @param minValue    
 * @param maxValue    
 * @param currentValue       
 * @param des     
 */
public void setValues(int minValue,int maxValue, int currentValue,String des) {
 mDes=des;
 mMaxValue=maxValue;
 mMinValue=minValue;
 //        
 if (currentValue > maxValue) {
  currentValue = maxValue;
 }
 //      
 float scale = (float) currentValue / maxValue;
 //    
 float currentAngle = scale * mAngle;
 //      
 setAnimation(0, currentAngle, currentValue,2500);
전체 코드:

/**
 * Created by ruancw on 2018/6/13.
 *        view
 */

public class ArcView extends View {

 //         Paint
 private Paint mArcPaint;
 //     paint
 private Paint mTextPaint;
 //       
 private float startAngle=135;
 //       
 private float endAngle=45;
 //                
 private float mAngle=270;
 //        
 private float mIncludedAngle=0;
 //        
 private float mStrokeWith=10;
 //       
 private String mDes="";
 //          /  
 private int mAnimatorValue,mMinValue,mMaxValue;
 //    XY  
 private float centerX,centerY;

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

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

 public ArcView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  //init();
 }

 private void initPaint() {
  //   paint
  mArcPaint=new Paint(Paint.ANTI_ALIAS_FLAG);
  //   
  mArcPaint.setAntiAlias(true);
  mArcPaint.setColor(Color.parseColor("#666666"));
  //     (   0-255)
  mArcPaint.setAlpha(100);
  //          
  mArcPaint.setStrokeJoin(Paint.Join.ROUND);
  mArcPaint.setStrokeCap(Paint.Cap.ROUND);
  //      
  mArcPaint.setStyle(Paint.Style.STROKE);
  mArcPaint.setStrokeWidth(dp2px(mStrokeWith));

  //     paint
  mTextPaint=new Paint();
  mTextPaint.setAntiAlias(true);
  mTextPaint.setColor(Color.parseColor("#FF4A40"));
  //         
  mTextPaint.setTextAlign(Paint.Align.CENTER);
  //mTextPaint.setTextSize(getResources().getDimensionPixelSize(R.dimen.dp_12));
  mTextPaint.setTextSize(dp2px(25));

 }

 @SuppressLint("DrawAllocation")
 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  centerX=getWidth()/2;
  centerY=getHeight()/2;
  //   paint
  initPaint();
  //    
  drawArc(canvas);
  //    
  drawText(canvas);
 }

 /**
  *     
  * @param canvas
  */
 private void drawText(Canvas canvas) {
  Rect mRect=new Rect();
  String mValue=String.valueOf(mAnimatorValue);
  //       
  mTextPaint.getTextBounds(mValue,0,mValue.length(),mRect);
  canvas.drawText(String.valueOf(mAnimatorValue),centerX,centerY+mRect.height(),mTextPaint);

  //        
  mTextPaint.setColor(Color.parseColor("#999999"));
  mTextPaint.setTextSize(dp2px(12));
  mTextPaint.getTextBounds(mDes,0,mDes.length(),mRect);
  canvas.drawText(mDes,centerX,centerY+2*mRect.height()+dp2px(10),mTextPaint);

  //     
  String minValue=String.valueOf(mMinValue);
  String maxValue=String.valueOf(mMaxValue);
  mTextPaint.setTextSize(dp2px(18));
  mTextPaint.getTextBounds(minValue,0,minValue.length(),mRect);
  canvas.drawText(minValue, (float) (centerX-0.6*centerX-dp2px(5)), (float) (centerY+0.75*centerY+mRect.height()+dp2px(5)),mTextPaint);
  //     
  mTextPaint.getTextBounds(maxValue,0,maxValue.length(),mRect);
  canvas.drawText(maxValue, (float) (centerX+0.6*centerX+dp2px(5)), (float) (centerY+0.75*centerY+mRect.height()+dp2px(5)),mTextPaint);
 }

 /**
  *        
  * @param canvas
  */
 private void drawArc(Canvas canvas) {
  //      
  RectF mRectF=new RectF(mStrokeWith+dp2px(5),mStrokeWith+dp2px(5),getWidth()-mStrokeWith-dp2px(5),getHeight()-mStrokeWith);
  canvas.drawArc(mRectF,startAngle,mAngle,false,mArcPaint);
  //           
  mArcPaint.setColor(Color.parseColor("#FF4A40"));
  //             
  canvas.drawArc(mRectF,startAngle,mIncludedAngle,false,mArcPaint);
 }

 /**
  *             
  *
  * @param startAngle      
  * @param currentAngle        
  * @param currentValue        
  * @param time        
  */
 private void setAnimation(float startAngle, float currentAngle,int currentValue, int time) {
  //                
  ValueAnimator progressAnimator = ValueAnimator.ofFloat(startAngle, currentAngle);
  progressAnimator.setDuration(time);
  progressAnimator.setTarget(mIncludedAngle);
  progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   @Override
   public void onAnimationUpdate(ValueAnimator animation) {
    mIncludedAngle = (float) animation.getAnimatedValue();
    //    ,        
    postInvalidate();
   }
  });
  //      
  progressAnimator.start();

  //         
  ValueAnimator valueAnimator = ValueAnimator.ofInt(mAnimatorValue, currentValue);
  valueAnimator.setDuration(2500);
  valueAnimator.setInterpolator(new LinearInterpolator());
  valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

   @Override
   public void onAnimationUpdate(ValueAnimator valueAnimator) {

    mAnimatorValue = (int) valueAnimator.getAnimatedValue();
    postInvalidate();
   }
  });
  valueAnimator.start();
 }

 /**
  *     
  * @param minValue    
  * @param maxValue    
  * @param currentValue       
  * @param des     
  */
 public void setValues(int minValue,int maxValue, int currentValue,String des) {
  mDes=des;
  mMaxValue=maxValue;
  mMinValue=minValue;
  //    
  if (currentValue > maxValue) {
   currentValue = maxValue;
  }
  //      
  float scale = (float) currentValue / maxValue;
  //    
  float currentAngle = scale * mAngle;
  //      
  setAnimation(0, currentAngle, currentValue,2500);
 }

 public float dp2px(float dp) {
  DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
  return dp * metrics.density;
 }
}
요약:Paint 의 붓 모양(Cap 과 Join 은 원호 형 으로 설정)을 설정 합 니 다.Canvas 의 drawArc 방법 으로 원호 와 drawText 로 텍스트 정 보 를 그립 니 다.ValueAnimator 는 데이터 와 현재 원호 진도 의 애니메이션 효 과 를 설정 합 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기