完全自定義控件-簡單環形進度條制作

JayHead 8年前發布 | 16K 次閱讀 安卓開發 Android開發 移動開發

昨天簡單熟悉了下canvas的API,今天來做個小demo鞏固下

回顧 完全自定義控件-Canvas之繪制基本形狀

簡單環形進度條制作

本文實現一個自定義的加載進度條,效果如下圖所示:

效果

實現步驟:

  1. 新建CircleProgressView類繼承View
  2. 在構造函數中初始化畫筆

    private void init() {
         mPaint = new Paint();
         mPaint.setColor(Color.BLACK);
         mPaint.setStyle(Paint.Style.STROKE);//繪圖為描邊模式
         mPaint.setStrokeWidth(20);//畫筆寬度
         mPaint.setAntiAlias(true);//抗鋸齒
     }
  3. 重寫onDraw

    主要邏輯為先繪制一個圓環,然后在它上面根據進度來繪制圓弧

    protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
         //得到畫布一半的寬度
         int center = getWidth() / 2;
         //定義圓的半徑
         int radius = 100;
         //定義一個圓
         mRectF = new RectF(center - radius, center - radius, center + radius, center + radius);
         if (!mChanged) {
             //設置畫筆的顏色
             mPaint.setColor(Color.BLUE);
             //畫一個圓,由于畫筆是描邊模式,所以展現的是個圓環
             canvas.drawCircle(center, center, radius, mPaint);
             //設置畫筆的顏色
             mPaint.setColor(Color.RED);
             //繪制圓弧,從12點方向(-90度)開始繪制,偏移角度為進度
             canvas.drawArc(mRectF, -90, mProgress, false, mPaint);
         } else {
             mPaint.setColor(Color.RED);
             canvas.drawCircle(center, center, radius, mPaint);
             mPaint.setColor(Color.BLUE);
             canvas.drawArc(mRectF, -90, mProgress, false, mPaint);
         }
         //進度更新方法
         startProgress();
     }

    進度更新方法

    private void startProgress() {
         //當view控件可見時,每50毫秒更新一次視圖
         if (isShown()) {
             postDelayed(new Runnable() {
                 @Override
                 public void run() {
                     mProgress += 10;
                     //如果偏移角度超過360,則至為0,并且跟換繪制顏色
                     if (mProgress >= 360) {
                         mProgress = 0;
                         mChanged = !mChanged;
                     }
                     invalidate();
                 }
             }, 50);
         }
     }

自定義屬性

  • 很明顯,我們不可能在代碼中寫死控件的參數,我們需要提供一些可定制屬性,方便在XML布局文件中對控件進行設置。

為控件添加自定義屬性的幾個步驟。

  1. 在values目錄下新建一個attrs.xml文件,內容如下:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
     <declare-styleable name="CircleProgressView">
         <attr name="firstColor" format="color"/> <!--圓環顏色-->
         <attr name="secondColor" format="color"/> <!--圓環顏色-->
         <attr name="circleWidth" format="integer"/><!--色帶寬度-->
     </declare-styleable>
    </resources>

    不同的屬性對應不同的format,屬性對應的format可以參考

    http://blog.csdn.net/pgalxx/article/details/6766677
  2. 獲取屬性

    在CircleProgressView的構造方法中獲取布局文件中的屬性

    //獲取TypedArray
    context.obtainStyledAttributes(attrs,R.styleable.RoundProgressBar)

    然后從TypedArray獲取我們定義的屬性

    public CircleProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView, defStyleAttr, 0);
    
         //獲取自定義屬性和默認值
         //getColor方法的第一個參數是我們在XML文件中定義的顏色,如果我們沒有給我們自定義的View定義顏色,他就會使用第二個參數中的默認值
         mFirstColor = ta.getColor(R.styleable.CircleProgressView_firstColor, Color.RED);
         mSecondColor = ta.getColor(R.styleable.CircleProgressView_secondColor, Color.BLUE);
         mCircleWidth = ta.getDimensionPixelSize(R.styleable.CircleProgressView_circleWidth,
                 (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics()));
    
         //釋放該實例,從而使其可被其他模塊復用
         ta.recycle();
         init();
     }
  3. 在onDraw()中使用

    protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
         //得到畫布一半的寬度
         int center = getWidth() / 4;
         //定義圓的半徑
         int radius = 100;
         //定義一個圓
         mRectF = new RectF(center - radius, center - radius, center + radius, center + radius);
         if (!mChanged) {
             //設置畫筆的顏色
             mPaint.setColor(mFirstColor);
             //畫一個圓,由于畫筆是描邊模式,所以展現的是個圓環
             canvas.drawCircle(center, center, radius, mPaint);
             //設置畫筆的顏色
             mPaint.setColor(mSecondColor);
             //繪制圓弧,從12點方向(-90度)開始繪制,偏移角度為進度
             canvas.drawArc(mRectF, -90, mProgress, false, mPaint);
         } else {
             mPaint.setColor(mSecondColor);
             canvas.drawCircle(center, center, radius, mPaint);
             mPaint.setColor(mFirstColor);
             canvas.drawArc(mRectF, -90, mProgress, false, mPaint);
         }
         //進度更新方法
         startProgress();
     }
  4. 在布局中使用

    第二個控件使用了自定義屬性

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical"
     tools:context="zhj.progressbardemo.MainActivity">
    
     <zhj.progressbardemo.CircleProgressView
         android:layout_width="match_parent"
         android:layout_height="259dp"
         />
    
     <zhj.progressbardemo.CircleProgressView
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginTop="50dp"
         app:circleWidth="30dp"
         app:firstColor="#f58a47"
         app:secondColor="#5be9d8"
         />
    </LinearLayout>

    效果展示

效果

這里是 項目地址

參考

https://segmentfault.com/a/1190000004624339

http://blog.csdn.net/lmj623565791/article/details/24500107

 

來自:http://www.jianshu.com/p/dfa2d62311ff

 

 本文由用戶 JayHead 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!