a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 系統 > Android > 正文

Android自定義View實現圓弧進度效果

2019-10-21 21:34:57
字體:
來源:轉載
供稿:網友

前言:Android開發中,自定義View實現自己想要的效果已成為一項必備的技能,當然自定義View也是Android開發中比較難的部分,涉及到的知識有Canvas(畫布),Paint(畫筆)等,自定義控件分為三種:一是直接繼承自View,完全的自定義;二是在原有控件的基礎上進行改造,達到自己想要的效果;還有一種就是自定義組合控件,將已有的控件根據自己的需要進行組合實現的效果。本人對自定義View也是一知半解,簡單記錄下自己學習自定義View(繼承自View)的過程,方便日后翻閱。

技術實現

1.ArcView繼承自View

2.Canvas(畫布)

3.Paint(畫筆)

效果圖:類似于QQ的計步效果

Android,View,圓弧,進度

1.繼承自View

(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")@Overrideprotected 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

//圓弧的paintmArcPaint=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

//中心文字的paintmTextPaint=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設置數據及當前圓弧進度的動畫效果。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 免费成人在线网站 | 欧美电影一区二区三区 | 久久精品网 | 亚洲自拍偷拍第一页 | 日本在线观看一区二区 | 国产精品中文字幕在线播放 | 在线中文字幕av | 国产精品人人做人人爽人人添 | 欧美一区二区精品 | 国产亚洲成av人片在线观看 | 97精品在线 | 色呦呦日韩 | 久久黄视频 | 久久久久久久久久久成人 | 二区视频 | 国产成人福利 | 黄视频网站免费看 | 欧美一区二区久久久 | 日日艹| av网站久久 | 亚洲黄色成人av | 欧美日韩一区二区在线 | 亚洲人成中文字幕在线观看 | 亚洲精品久久久久久久久久久久久 | 久久久精品免费观看 | 日韩一区二区在线观看视频 | 99这里只有精品 | 国产视频精品视频 | 国产精品久久久久久吹潮 | 在线不卡一区 | 亚洲h网站 | 日韩欧美一级精品久久 | 五月婷婷之激情 | 在线观看成人av | 中文字幕一区二区三区乱码图片 | 亚洲欧美日韩另类精品一区二区三区 | 久久久久久久久久久久久久久久久久久久 | 久久久亚洲一区二区三区 | 夜夜av| 在线国产一区二区 | 中文成人av |