自定義View實現Android圓形進度條
原理:
通過繼承Android的View類,重寫onDraw方法。
實現:
這次就直接上代碼了
然后是XML,因為要用到自定義屬性
最后是在代碼里的用法
然后是效果圖

來自:http://blog.csdn.net/windowsxp2014/article/details/43342581
import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Paint.FontMetrics; import android.graphics.Paint.Style; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; import android.widget.ImageView; import android.widget.SeekBar; public class CycleView extends View { Paint mPaint; int progress = 30; int start_degree = -90; public CycleView(Context context, AttributeSet attrs) { super(context, attrs); InitResources(context, attrs); } int background_int; int progress_int; float layout_width_float; int textColor_int; float textSize_float; int max_int; Drawable thumb_double; int thumbSize_int; private void InitResources(Context context, AttributeSet attrs) { TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.windows); background_int = mTypedArray.getColor(R.styleable.windows_background, 0xFF87cfe8); progress_int = mTypedArray.getColor(R.styleable.windows_progressDrawable, 0xFFabd800); layout_width_float = mTypedArray.getDimension(R.styleable.windows_layout_width, 7); textColor_int = mTypedArray.getColor(R.styleable.windows_textColor, 0xFFada1de); textSize_float = mTypedArray.getDimension(R.styleable.windows_textSize, 50); max_int = mTypedArray.getInt(R.styleable.windows_max, 100); progress = mTypedArray.getInt(R.styleable.windows_progress, 20); thumb_double = mTypedArray.getDrawable(R.styleable.windows_thumb); thumbSize_int = mTypedArray.getInt(R.styleable.windows_thumbSize, 30); mTypedArray.recycle(); if (thumb_double == null) { Bitmap bitmap = Bitmap.createBitmap(thumbSize_int, thumbSize_int, Bitmap.Config.ARGB_8888); // 圖片畫片 Canvas cas = new Canvas(bitmap); Paint paint = new Paint(); paint.setStyle(Style.FILL); paint.setColor(0xFF68ba32); int center = thumbSize_int / 2; int radius = center - 4; cas.drawCircle(center, center, radius, paint); thumb_double = new BitmapDrawable(getResources(), bitmap); } mPaint = new Paint(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawProgressView(canvas); } private void drawProgressView(Canvas canvas) { InitOval(canvas); drawBackground(canvas); drawProgress(canvas); drawProgressText(canvas); } RectF oval; private void InitOval(Canvas canvas) { int center = getWidth() / 2; int radius = (int) (center - thumbSize_int / 2); // 畫布中央減去半徑就是左上角 int left_top = center - radius; // 畫布中央加上半徑就是右下角 int right_bottom = center + radius; if (oval == null) { oval = new RectF(left_top, left_top, right_bottom, right_bottom); } } /** * 繪制進度文字 * * @param canvas */ private void drawProgressText(Canvas canvas) { mPaint.setTextSize(textSize_float); mPaint.setColor(textColor_int); mPaint.setStrokeWidth(2); mPaint.setStyle(Style.FILL); String progresstext = progress + "%"; float text_left = (getWidth() - mPaint.measureText(progresstext)) / 2; FontMetrics fontMetrics = mPaint.getFontMetrics(); // 繪制文字是底部對齊 float text_top = (float) ((getHeight() / 2 + Math.ceil(fontMetrics.descent - fontMetrics.ascent) / 2)); canvas.drawText(progresstext, text_left, text_top, mPaint); } private void drawProgress(Canvas canvas) { // 設置進度 mPaint.setColor(progress_int); mPaint.setStrokeWidth(layout_width_float); float seek = 0; if (max_int > 0) { seek = (float) progress / max_int * 360; } canvas.drawArc(oval, start_degree, seek, false, mPaint); canvas.save(); int center = getWidth() / 2; int radius = (int) (center - thumbSize_int / 2); double cycle_round = (seek + start_degree) * Math.PI / 180; float x = (float) (Math.cos(cycle_round) * (radius) + center - thumbSize_int / 2); float y = (float) (Math.sin(cycle_round) * (radius) + center - thumbSize_int / 2); thumb_double.setBounds(0, 0, thumbSize_int, thumbSize_int); canvas.translate(x, y); thumb_double.draw(canvas); canvas.restore(); } private void drawBackground(Canvas canvas) { mPaint.setStrokeWidth(layout_width_float); mPaint.setStyle(Paint.Style.STROKE); mPaint.setAntiAlias(true); // 設置背景 mPaint.setColor(background_int); canvas.drawArc(oval, start_degree, 360, false, mPaint); } /** * 查看Seekbar源碼 * * @param progress */ public synchronized void setProgress(int progress) { if (progress > max_int) { progress = max_int; } this.progress = progress; postInvalidate(); } public int getProgress() { return this.progress; } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (thumb_double != null) { thumb_double.setCallback(null); thumb_double = null; } } }
然后是XML,因為要用到自定義屬性
<?xml version="1.0" encoding="utf-8"?> <resources> <!-- 參考Seekbar --> <declare-styleable name="windows"> <!-- 背景顏色 --> <attr name="background" format="color" /> <!-- 進度顏色 --> <attr name="progressDrawable" format="color" /> <!-- 寬度 --> <attr name="layout_width" format="dimension" /> <!-- 字體顏色 --> <attr name="textColor" format="color" /> <!-- 字體大小 --> <attr name="textSize" format="dimension" /> <!-- 最大進度 --> <attr name="max" format="integer" /> <!-- 進度 --> <attr name="progress" format="integer" /> <!-- 進度點 --> <attr name="thumb" format="reference" /> <!-- 進度點寬高 --> <attr name="thumbSize" format="integer" /> </declare-styleable> </resources>
最后是在代碼里的用法
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <com.windows.canvas.CycleView android:layout_centerInParent="true" xmlns:windows="http://schemas.android.com/apk/res/com.finals.canvas" android:layout_width="150dp" android:layout_height="150dp" /> </RelativeLayout>
然后是效果圖

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