Android自定義view實現半圓環效果
本文實例為大傢分享瞭Android自定義view實現半圓環的具體代碼,供大傢參考,具體內容如下
1.自定義屬性
<declare-styleable name="SemicircleView"> <attr name="radius" format="dimension" /> <attr name="strokeWidth" format="dimension" /> <attr name="bgArcColor" format="color" /> <attr name="usedArcColor" format="color" /> <attr name="usedTextSize" format="dimension" /> <attr name="usedPercentTextSize" format="dimension" /> <attr name="percentTextSize" format="dimension" /> </declare-styleable>
2.自定義View
package com.anhuitelecom.share.activity.view; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Paint.FontMetrics; import android.graphics.Rect; import android.graphics.RectF; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.view.View; import com.anhuitelecom.share.activity.R; /** * * @ClassName: SemicircleView * @Description: 自定義view 實現半圓弧 * @author chenzheng * @date 2017-2-21 下午2:44:16 */ public class SemicircleView extends View{ //線圓弧畫筆 private Paint mLineArcPaint; //背景圓弧畫筆 private Paint mBackgroudArcPaint; //已使用圓弧畫筆 private Paint mUsedArcPaint; //已使用以及流量文字畫筆 private Paint mUsedTxtPaint; //已使用百分比文字畫筆 private Paint mUsedPercentTxtPaint; //百分號畫筆 private Paint mPercentTxtPaint; //最外層圓弧線顏色 private int mLineArcColor; //背景圓環顏色 private int mBackgroundArcColor; //已使用圓弧顏色 private int mUsedArcColor; //圓弧半徑 private float mArcRadius; //外線大半徑 private float mLineRadius; //圓弧寬度 private float mArcStrokeWidth; // 圓心x坐標 private int mXCenter; // 圓心y坐標 private int mYCenter; //已使用百分比 private float mProgress=0; //動畫展示弧度 private float mShowProgress; private Context mContext; //已使用和總流量 private String mUserdAndAll; private float mUsedTextSize; private float mUsedPercentTextSize; private float mPercentTextSize; private float mUsedPercentTxtHeight; //private CircleThread private Handler circleHandler = new Handler(){ public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what == 1){ float temp = (Float)msg.obj; setShowProgress(temp); } }; }; public SemicircleView(Context context) { this(context, null); } public SemicircleView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public SemicircleView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); mContext = context; // 獲取自定義的屬性 initAttrs(context, attrs); initVariable(); } private void initAttrs(Context context, AttributeSet attrs) { TypedArray typeArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SemicircleView, 0, 0); mLineRadius = typeArray.getDimension(R.styleable.SemicircleView_radius, 120); mArcStrokeWidth = typeArray.getDimension(R.styleable.SemicircleView_strokeWidth, 12); mBackgroundArcColor = typeArray.getColor(R.styleable.SemicircleView_bgArcColor, 0xFFFFFFFF); mUsedArcColor = typeArray.getColor(R.styleable.SemicircleView_usedArcColor, 0xFFFF3D3B); mUsedTextSize = typeArray.getDimension(R.styleable.SemicircleView_usedTextSize, 14); mUsedPercentTextSize = typeArray.getDimension(R.styleable.SemicircleView_usedPercentTextSize, 52); mPercentTextSize = typeArray.getDimension(R.styleable.SemicircleView_percentTextSize, 16); typeArray.recycle(); } private void initVariable() { //初始化一些值 mLineRadius = mLineRadius + mArcStrokeWidth / 2; mArcRadius = mLineRadius-1.8f*mArcStrokeWidth; mLineArcColor = 0x33FFFFFF; mUserdAndAll = "0M/0M"; //外層線圓弧畫筆設置 mLineArcPaint = new Paint(); mLineArcPaint.setAntiAlias(true); mLineArcPaint.setColor(mLineArcColor); mLineArcPaint.setStyle(Paint.Style.STROKE); mLineArcPaint.setStrokeWidth(1); mLineArcPaint.setStrokeCap(Paint.Cap.ROUND);//開啟顯示邊緣為圓形 //背景圓弧畫筆設置 mBackgroudArcPaint = new Paint(); mBackgroudArcPaint.setAntiAlias(true); mBackgroudArcPaint.setColor(mBackgroundArcColor); mBackgroudArcPaint.setStyle(Paint.Style.STROKE); mBackgroudArcPaint.setStrokeWidth(mArcStrokeWidth); mBackgroudArcPaint.setStrokeCap(Paint.Cap.ROUND);//開啟顯示邊緣為圓形 //已使用多少圓環畫筆設置 mUsedArcPaint = new Paint(); mUsedArcPaint.setAntiAlias(true); mUsedArcPaint.setColor(mUsedArcColor); mUsedArcPaint.setStyle(Paint.Style.STROKE); mUsedArcPaint.setStrokeWidth(mArcStrokeWidth); mUsedArcPaint.setStrokeCap(Paint.Cap.ROUND);//開啟顯示邊緣為圓形 mUsedTxtPaint = new Paint(); mUsedTxtPaint.setAntiAlias(true); mUsedTxtPaint.setStyle(Paint.Style.FILL); mUsedTxtPaint.setColor(0x80FFFFFF); mUsedTxtPaint.setTextSize(mUsedTextSize); //百分比數字畫筆 mUsedPercentTxtPaint = new Paint(); mUsedPercentTxtPaint.setAntiAlias(true); mUsedPercentTxtPaint.setStyle(Paint.Style.FILL); mUsedPercentTxtPaint.setColor(0xFFFFFFFF); mUsedPercentTxtPaint.setTextSize(mUsedPercentTextSize); //百分號畫筆 mPercentTxtPaint = new Paint(); mPercentTxtPaint.setAntiAlias(true); mPercentTxtPaint.setStyle(Paint.Style.FILL); mPercentTxtPaint.setColor(0xFFFFFFFF); mPercentTxtPaint.setTextSize(mPercentTextSize); //獲取字體高度 FontMetrics fm = mUsedPercentTxtPaint.getFontMetrics(); mUsedPercentTxtHeight = (int) Math.ceil(fm.descent - fm.ascent); } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); mXCenter = getWidth() / 2; mYCenter = getHeight() / 2; RectF lineOval = new RectF(); lineOval.left = (mXCenter - mLineRadius); lineOval.top = (mYCenter - mLineRadius); lineOval.right = mLineRadius * 2 + (mXCenter - mLineRadius); lineOval.bottom = mLineRadius * 2 + (mYCenter - mLineRadius); RectF oval = new RectF(); oval.left = (mXCenter - mArcRadius); oval.top = (mYCenter - mArcRadius); oval.right = mArcRadius * 2 + (mXCenter - mArcRadius); oval.bottom = mArcRadius * 2 + (mYCenter - mArcRadius); //繪制最外面圓弧線 canvas.drawArc(lineOval, -225, 270, false, mLineArcPaint); //繪制背景圓弧 canvas.drawArc(oval, -225, 270, false, mBackgroudArcPaint); //繪制已使用圓弧 float mShowDegree = mShowProgress/100*270; canvas.drawArc(oval, -225, mShowDegree, false, mUsedArcPaint); //已使用文字 Rect usedRect = new Rect(); String usedStr = "已使用"; mUsedTxtPaint.getTextBounds(usedStr, 0, usedStr.length(), usedRect); int usedX = mXCenter - usedRect.width() / 2; canvas.drawText(usedStr, usedX, mYCenter-mArcRadius*0.6f, mUsedTxtPaint); //已使用和總流量 Rect ua_rect = new Rect(); mUsedTxtPaint.getTextBounds(mUserdAndAll, 0, mUserdAndAll.length(), ua_rect); int uaX = mXCenter - ua_rect.width() / 2; canvas.drawText(mUserdAndAll, uaX, mYCenter+mArcRadius*0.6f, mUsedTxtPaint); //百分比數字 String progressStr = (int)mShowProgress+""; String percentStr = "%"; float usedPercentWidth = mUsedPercentTxtPaint.measureText(progressStr, 0, progressStr.length()); float percentWidth = mPercentTxtPaint.measureText(percentStr, 0, percentStr.length()); float upX = mXCenter-(usedPercentWidth + percentWidth)/2; canvas.drawText(progressStr, upX, mYCenter+mUsedPercentTxtHeight/3, mUsedPercentTxtPaint); float pX = upX + usedPercentWidth; canvas.drawText(percentStr, pX, mYCenter+mUsedPercentTxtHeight/3, mPercentTxtPaint); } private void setShowProgress(float progress){ this.mShowProgress = progress; postInvalidate(); } public void setProgress(float progress) { mProgress = progress; new Thread(new CircleThread()).start(); } public void setUsedArcColor(int usedArcColor) { this.mUsedArcColor = usedArcColor; if(mUsedArcPaint!=null){ mUsedArcPaint.setColor(mUsedArcColor); } } public void setUsedAndAll(String usedAndAll) { this.mUserdAndAll = usedAndAll; } public static int dp2px(Context context, float dipValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dipValue * scale + 0.5f); } public static int sp2px(Context context, float spValue) { final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; return (int) (spValue * fontScale + 0.5f); } public static int px2sp(Context context, float pxValue) { final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; return (int) (pxValue / fontScale + 0.5f); } private class CircleThread implements Runnable{ int m=0; float i=0; @Override public void run() { // TODO Auto-generated method stub while(!Thread.currentThread().isInterrupted()){ try { Thread.sleep(30); m++; Message msg = new Message(); msg.what = 1; if(i < mProgress){ i += m; msg.obj = i; circleHandler.sendMessage(msg); }else{ i = mProgress; msg.obj = i; circleHandler.sendMessage(msg); return; } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
3.外部調用
<com.view.SemicircleView android:id="@+id/semicircleView" android:layout_width="215dp" android:layout_height="215dp" android:layout_gravity="center_horizontal" android:layout_marginTop="30dp" halfArc:bgArcColor="#ffffff" halfArc:percentTextSize="16sp" halfArc:radius="100dp" halfArc:strokeWidth="11dp" halfArc:usedArcColor="#FF3D3B" halfArc:usedPercentTextSize="52sp" halfArc:usedTextSize="14sp" />
semicircleView.setUsedAndAll("170M/200M"); semicircleView.setProgress(81);
4.實現效果圖
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Android自定義view實現圓環進度條效果
- Android自定義view貝塞爾曲線
- Android使用貝塞爾曲線畫心形
- Android顏色處理SweepGradient掃描及梯度渲染示例
- android實現倒計時動態圈