Android自訂View實現簡單的圓形Progress效果_Android

來源:互聯網
上載者:User

先給大家展示下效果圖,如果感覺不錯,請參考實現思路:

我們要實現一個自訂的再一個圓形中繪製一個弧形的自訂View,思路是這樣的:

  先要建立一個類ProgressView,繼承自View類,然後重寫其中的兩個構造方法,一個是一個參數的,一個是兩個參數的,因為我們要在xml檔案中使用該自訂控制項,所以必須要定義這個兩個參數的建構函式。建立完了這個類後,我們先不去管它,先考慮我們實現的這個自訂View,我們想讓它的哪些部分可以由使用者自己指定,比如說這個Demo中我們讓他的外面圓的外邊框顏色和寬度,還有扇形部分的顏色,扇形增長的速度等等屬性,這時候我們要在項目工程目錄的res/values目錄下建立一個資源檔命名為attrs(注意,名字隨意,只是大多數情況下都這麼叫而已),然後我們在這個資源檔中添加我們想要的屬性,如下:

<?xml version="1.0" encoding="utf-8"?><resources><declare-styleable name="ProgressView"><!--circleColor 設定圓形邊框的顏色 sweepColor設定扇形變換的顏色startAngle 設定起始角度 sweepStep 設定變換的步長--><attr name="circleColor" format="color|reference"></attr><attr name="sweepColor" format="color|reference"></attr><attr name="startAngle" format="integer"></attr><attr name="sweepStep" format="integer"></attr><attr name="padding" format="integer"></attr></declare-styleable></resources>

可以看到,<declare-styleable>標籤中的name屬性是為了方便我們擷取AttributeSet時候使用,而<attr>標籤中name,則是我們希望控制項可以自訂的屬性部分,類似於xml檔案中的android:name=""等標籤的使用。format屬性是設定該屬性可以接受什麼類型的參數。

定義好了自訂資源類,我們開始寫ProgressView中的主要代碼:

package com.yztc.customprogressview;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.util.AttributeSet;import android.view.View;/*** 自訂的*/public class ProgressView extends View {private int sweepStep = 10;//扇形變換的步長(就是角度)private int padding = 40;//外邊框距離扇形的距離 填充private int circleColor = Color.GRAY;//邊框的顏色private int sweepColor = Color.BLUE;//扇形顏色private int startAngle = 90;//起始角度//設定外邊框圓的邊框粗細private int storke = 20;private int sweepAngle = 0;//掃過的角度private static final int DEFAULT_WIDTH = 200;private static final int DEFAULT_HEIGHT = 200;public ProgressView(Context context) {super(context);}//如果要在xml檔案中使用該自訂控制項,則必須重寫兩個參數的建構函式//因為我們使用自訂的屬性的時候,會預設傳遞過來一個AttributeSet集合public ProgressView(Context context, AttributeSet attrs) {super(context, attrs);TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ProgressView);if (array != null) {//擷取我們在xml中設定的各個自訂屬性sweepStep = array.getInteger(R.styleable.ProgressView_sweepStep, sweepStep);padding = array.getInteger(R.styleable.ProgressView_padding, padding);circleColor = array.getColor(R.styleable.ProgressView_circleColor, circleColor);sweepColor = array.getColor(R.styleable.ProgressView_sweepColor, sweepColor);startAngle = array.getInteger(R.styleable.ProgressView_startAngle, startAngle);//回收TypeArray資源array.recycle();}}/*** 先繪製外邊框 --內部扇形** @param canvas*/@Overrideprotected void onDraw(Canvas canvas) {Paint mPaint = new Paint();mPaint.setAntiAlias(true); //設定消除鋸齒//繪製外層的圓框mPaint.setColor(circleColor);mPaint.setStrokeWidth(storke);mPaint.setStyle(Paint.Style.STROKE);//設定圓形為空白心的圓//這裡我們得到控制項的Height和Width,根據Heigh和Width來確定圓心的位置,來繪製外層圓canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2 - storke / 2, mPaint);// Log.d("tag", "onDraw: "+getWidth());invalidate();//請求重新繪製view//繪製內部的扇形mPaint.setStyle(Paint.Style.FILL_AND_STROKE);mPaint.setColor(sweepColor);/*drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,Paint paint)RectF oval 指定扇形的矩形容器物件 指定圓弧的外輪廓的矩形float startAngle 表示圓弧的起始角度float sweepAngle 表示圓弧走過掃過的角度 順時針方向boolean useCenter 如果設定為true 在繪製圓弧時將圓心包括在內,是指以一個固定的圓心來繪製弧形(扇形),如果指定為false,則不規則繪製扇形Paint paint 畫筆 顏色 填充public RectF(float left, float top, float right, float bottom)float left 矩形的左邊點(左切點)的x座標float top 矩形上邊點(上切點)的y軸座標float right, 矩形的右邊點(右切點)的x座標float bottom 矩形的下邊點(下切點)的y座標*///RectF中的四個參數,分別對應其內切圓的四個切點的座標RectF rectF = new RectF(padding + storke, padding + storke, getWidth() - padding - storke, getWidth() - padding - storke);canvas.drawArc(rectF, startAngle, sweepAngle, true, mPaint);sweepAngle += sweepStep;//根據步長更新掃過的角度sweepAngle = sweepAngle > 360 ? 0 : sweepAngle;invalidate();//重繪view}//因為我們是繼承的View來自訂的View,所以onMeasure()方法要重寫@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int wMode = MeasureSpec.getMode(widthMeasureSpec);int hMode = MeasureSpec.getMode(heightMeasureSpec);int wSize = MeasureSpec.getSize(widthMeasureSpec);int hSize = MeasureSpec.getSize(heightMeasureSpec);//因為繪製的是圓,所以判斷一下高度或者寬度中的一個就可以。switch (wMode) {case MeasureSpec.AT_MOST://android:layout_width="warp_content"//擷取螢幕像素float density = getResources().getDisplayMetrics().density;wSize = (int) (DEFAULT_WIDTH * density);hSize = (int) (DEFAULT_HEIGHT * density);break;//當在xml中指定控制項的寬高為match_parent或者指定數值的寬高時,回調以下代碼case MeasureSpec.EXACTLY://android:layout_width="match_parent" android:layout_width="40dp"wSize = hSize = Math.min(wSize, hSize);break;}//只要重寫onMeasure()方法,一定要調用以下方法,不然會報錯setMeasuredDimension(wSize, hSize);}}

我們先畫一個外部的圓,也就是都用drawCircle()方法,這裡我們調用getWidth(),getHeight()表示得到布局中設定的控制項的尺寸,因為是圓,所以可以使用getWidth()/2來表示圓心位置。而畫內部弧形的時候,確定其圓心位置,左部點的座標是外面圓的邊框加上弧形與原的間距padding來確定,右側點的x座標則是getWidth()得到總長度,減去邊框寬度,再減去padding得到,上邊距和下邊距同樣,不明白的畫一個圖立馬明白。大部分不好理解的地方都有注釋,只要認真看不會看不明白的~

然後就是在布局中引入我們的自訂View了:

<?xml version="1.0" encoding="utf-8"?><RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="@dimen/activity_vertical_margin"android:paddingLeft="@dimen/activity_horizontal_margin"android:paddingRight="@dimen/activity_horizontal_margin"android:paddingTop="@dimen/activity_vertical_margin"tools:context="com.yztc.customprogressview.MainActivity"><com.yztc.customprogressview.ProgressViewandroid:id="@+id/pv"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#0000ff"app:padding="20"app:circleColor="#aa0000"app:sweepColor="#00aa00"app:sweepStep="1"app:startAngle="180"/></RelativeLayout>

需要注意的是我們需要在布局的跟標籤下面加上這麼一段代碼:xmlns:app="http://schemas.android.com/apk/res-auto"

用來指定我們可以使用自己再attrs中自訂的屬性啦~,使用的形式就是app:你定義的屬性。當然,這個app也不是固定的寫法,只要跟上面你加的那段代碼的xmlns後面的欄位一致就可以了~

還有需要注意的是:

預設使用Canvas類的drawCircle()方法來畫圓的時候,圓的半徑是你指定的半徑,再加上一半的邊長,比如你的邊框size=10,radius=50,則實際空心部分的半徑為55.注意這點,否則畫出來的圓的四個切點位置會與其他位置有些不一樣,類似出現鋸齒的效果。具體請看drawCircle()的Rect邊框問題。

以上所述是小編給大家介紹的Android自訂View實現簡單的圓形Progress效果,希望對大家有所協助,如果大家有任何疑問歡迎給我留言,小編會及時回複大家的!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.