完全自定義控件-簡單環形進度條制作
昨天簡單熟悉了下canvas的API,今天來做個小demo鞏固下
簡單環形進度條制作
本文實現一個自定義的加載進度條,效果如下圖所示:
效果
實現步驟:
- 新建CircleProgressView類繼承View
-
在構造函數中初始化畫筆
private void init() { mPaint = new Paint(); mPaint.setColor(Color.BLACK); mPaint.setStyle(Paint.Style.STROKE);//繪圖為描邊模式 mPaint.setStrokeWidth(20);//畫筆寬度 mPaint.setAntiAlias(true);//抗鋸齒 }
-
重寫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布局文件中對控件進行設置。
為控件添加自定義屬性的幾個步驟。
-
在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 -
獲取屬性
在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(); }
-
在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(); }
-
在布局中使用
第二個控件使用了自定義屬性
<?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 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!