1. 程式人生 > >android 圓形進度條的簡單實現

android 圓形進度條的簡單實現

在網上看了些進度條效果,於是就想寫關於這方面部落格,先看下今天要實現一些進度條的效果圖:


當然要實現這些效果是基於你對canvas類繪製一些圖形是瞭解的,否則估計也不好看懂,我儘量講的詳細點,

先從簡單的畫圓開始一步步把這個效果實現出來,這樣幾乎每個人都能看的懂,

畫圓的程式碼:

package com.example.pbdemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import 
android.util.AttributeSet; import android.view.View; /** * Created by admin on 2016/7/5. */ public class MyProgressView extends View { private Paint mPaint; public MyProgressView(Context context) { this(context,null); } public MyProgressView(Context context, AttributeSet attrs) { this
(context, attrs,0); } public MyProgressView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPaint = new Paint(); mPaint.setColor(Color.BLUE);//設定畫筆的顏色 mPaint.setStrokeWidth(8);//設定畫筆的寬度 mPaint.setAntiAlias(true);//設定看鋸齒 mPaint.setStyle(Paint.Style.STROKE
);//設定成空心 } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawCircle(100,100,80,mPaint); } }
效果:


現在畫個弧,示意圖:


public class MyProgressView extends View {
    private Paint mPaint;
    public MyProgressView(Context context) {
        this(context,null);
}
    public MyProgressView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
}
    public MyProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
mPaint = new Paint();
mPaint.setColor(Color.BLUE);//設定畫筆的顏色
mPaint.setStrokeWidth(8);//設定畫筆的寬度
mPaint.setAntiAlias(true);//設定看鋸齒
mPaint.setStyle(Paint.Style.STROKE);//設定成空心
}
    @Override
protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
canvas.drawCircle(100,100,80,mPaint);
RectF rectF = new RectF(20,20,180,180);
mPaint.setColor(Color.YELLOW);
canvas.drawArc(rectF,0,30,false,mPaint);
}
}
效果圖:


ok,現在就差讓弧度進行動態的改變,這樣就達到黃色所表示的弧度是動態的,這就有個簡單的計算,比如進度條最大值是100,剛開始是0,每過1秒後+1,同時去重新整理介面,那麼弧度怎麼算呢,你看當進度條最大值為100時,剛好弧度走一圈,一圈是360度,假如當前進度為10,那麼它所表示弧度=10/100*360,那麼現在就可以寫程式碼了,根據這個思路

package com.example.pbdemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
 * Created by admin on 2016/7/5.
 */
public class MyProgressView extends View {
    private static final String TAG ="MyProgressView" ;
    private Paint mPaint;//這是畫圓所用的畫筆
private Paint anglePaint;//這是畫弧的畫筆
private int startingDegree = 0;//開始弧度
private int max = 100;
    private int progress;
    public MyProgressView(Context context) {
        this(context,null);
}
    public MyProgressView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
}
    public MyProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
mPaint = new Paint();
anglePaint = new Paint();
anglePaint.setStrokeWidth(8);
anglePaint.setColor(Color.YELLOW);
mPaint.setColor(Color.BLUE);//設定畫筆的顏色
mPaint.setStrokeWidth(8);//設定畫筆的寬度
mPaint.setAntiAlias(true);//設定看鋸齒
mPaint.setStyle(Paint.Style.STROKE);//設定成空心
anglePaint.setStyle(Paint.Style.STROKE);//設定成空心
anglePaint.setAntiAlias(true);
}
    @Override
protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
canvas.drawCircle(100,100,80,mPaint);
RectF rectF = new RectF(20,20,180,180);
canvas.drawArc(rectF,getStartingDegree(),getProgressAngle(),false,anglePaint);
}
    /**
     * 弧度從哪角度開始
* @return
*/
public int getStartingDegree() {
        return startingDegree;
}

    /**
     * 設定進度值,實時更新進度
* @param progress
*/
public void setProgress(int progress){
        this.progress = progress;
        if (this.progress > max) {
            this.progress %= max;
}
        invalidate();
}
    /**
     * 獲取當前進度值
* @return
*/
public int getProgress(){
        return progress;
}
    /**
     * 弧度所經過的度
* @return
*/
private float getProgressAngle() {
        return getProgress() / (float) max * 360f;
}
}

要100毫秒去更新進度值

public class MainActivity extends AppCompatActivity {
    private Timer timer;
    private MyProgressView myprogressview;
@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myprogressview = (MyProgressView) findViewById(R.id.myprogressview);
timer = new Timer();
timer.schedule(new TimerTask() {
            @Override
public void run() {
                runOnUiThread(new Runnable() {
                    @Override
public void run() {
                        myprogressview.setProgress(myprogressview.getProgress()+1);
}
                });
}
        }, 1000, 100);
}
}
效果:


現在新增一個需求就是在圓的中心點顯示當前進度值,這個就要計算文字所在的座標x,y了

分析圖:


程式碼如下:

public class MyProgressView extends View {
    private static final String TAG ="MyProgressView" ;
    private Paint mPaint;//這是畫圓所用的畫筆
private Paint textPaint;//繪製文字的畫筆
private Paint anglePaint;//這是畫弧的畫筆
private int startingDegree = 0;//開始弧度
private int max = 100;
    private int progress;
    public MyProgressView(Context context) {
        this(context,null);
}
    public MyProgressView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
}
    public MyProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
textPaint = new Paint();
textPaint.setColor(Color.RED);
textPaint.setTextSize(24);//設定文字的大小
textPaint.setAntiAlias(true);
mPaint = new Paint();
anglePaint = new Paint();
anglePaint.setStrokeWidth(8);
anglePaint.setColor(Color.YELLOW);
mPaint.setColor(Color.BLUE);//設定畫筆的顏色
mPaint.setStrokeWidth(8);//設定畫筆的寬度
mPaint.setAntiAlias(true);//設定看鋸齒
mPaint.setStyle(Paint.Style.STROKE);//設定成空心
anglePaint.setStyle(Paint.Style.STROKE);//設定成空心
anglePaint.setAntiAlias(true);
}
    @Override
protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
canvas.drawCircle(100,100,80,mPaint);
RectF rectF = new RectF(20,20,180,180);
        float textHeight = textPaint.descent() + textPaint.ascent();//算出文字的高度
String text = getProgress()+"%";
canvas.drawText(text,20+80-textPaint.measureText(text)/2,20+80-textHeight/2,textPaint);
canvas.drawArc(rectF,getStartingDegree(),getProgressAngle(),false,anglePaint);
}
    /**
     * 弧度從哪角度開始
* @return
*/
public int getStartingDegree() {
        return startingDegree;
}

    /**
     * 設定進度值,實時更新進度
* @param progress
*/
public void setProgress(int progress){
        this.progress = progress;
        if (this.progress > max) {
            this.progress %= max;
}
        invalidate();
}
    /**
     * 獲取當前進度值
* @return
*/
public int getProgress(){
        return progress;
}
    /**
     * 弧度所經過的度
* @return
*/
private float getProgressAngle() {
        return getProgress() / (float) max * 360f;
}
}

MainActivity類中的程式碼不變,那麼在這不貼出來了,現在看效果:


現在實現這個效果;


這裡有一個值是定的,就是那個預設的度數,比如是0.2*360,那麼進度要跑的就是0.8*360,

程式碼如下:

package com.example.pbdemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/**
 * Created by admin on 2016/7/5.
 */
public class MyProgressView extends View {
    private static final String TAG ="MyProgressView" ;
    private Paint textPaint;//繪製文字的畫筆
private Paint anglePaint;//這是畫弧的畫筆
private int max = 100;
    private int progress;
    private float arcAngle = 360*0.8f;//
public MyProgressView(Context context) {
        this(context,null);
}
    public MyProgressView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
}
    public MyProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
initPainters();
}
    @Override
protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
RectF rectF = new RectF(100,100,400,400);
        float startAngle = (float) (90+0.1*360f);
        float sweepAngle =  progress / (float)max * arcAngle;
canvas.drawArc(rectF,startAngle,sweepAngle,false,anglePaint);
}

    /**
     * 設定進度值,實時更新進度
* @param progress
*/
public void setProgress(int progress){
        this.progress = progress;
        if (this.progress > max) {
            this.progress %= max;
}
        invalidate();
}
    /**
     * 獲取當前進度值
* @return
*/
public int getProgress(){
        return progress;
}
    private void initPainters() {
        textPaint = new Paint();
textPaint.setColor(Color.RED);
textPaint.setTextSize(24);//設定文字的大小
textPaint.setAntiAlias(true);
anglePaint = new Paint();
anglePaint.setStrokeWidth(8);
anglePaint.setColor(Color.parseColor("#D2691E"));
anglePaint.setStyle(Paint.Style.STROKE);//設定成空心
anglePaint.setAntiAlias(true);
anglePaint.setStrokeCap(Paint.Cap.ROUND);
}
}
每秒重新整理一次,
myprogressview = (MyProgressView) findViewById(R.id.myprogressview);
timer = new Timer();
timer.schedule(new TimerTask() {
    @Override
public void run() {
        runOnUiThread(new Runnable() {
            @Override
public void run() {
                myprogressview.setProgress(myprogressview.getProgress()+1);
}
        });
}
}, 1000, 100);
效果:


分析圖:


現在只是實現了第一步,我們看著效果圖是弧度是有二個顏色的,現在把弧度沒掃過的顏色也繪製出來,這個其實很簡單,底層是繪製一種顏色,上面是弧度經過的顏色

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
RectF rectF = new RectF(100,100,400,400);
    float startAngle = (float) (90+0.1*360f);
    float sweepAngle =  progress / (float)max * arcAngle;
anglePaint.setColor(Color.parseColor("#D2691E"));
canvas.drawArc(rectF, startAngle, arcAngle, false, anglePaint);
anglePaint.setColor(Color.parseColor("#9ACD32"));
canvas.drawArc(rectF,startAngle,sweepAngle,false,anglePaint);
}
效果:


現在進一步完善我們想要的效果,需要在圓的中心顯示當前進度值,這個和上面講的進度條中繪製文字是一樣的,

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
RectF rectF = new RectF(100,100,400,400);
    float startAngle = (float) (90+0.1*360f);
    float sweepAngle =  progress / (float)max * arcAngle;
anglePaint.setColor(Color.parseColor("#D2691E"));
canvas.drawArc(rectF, startAngle, arcAngle, false, anglePaint);
anglePaint.setColor(Color.parseColor("#9ACD32"));
canvas.drawArc(rectF,startAngle,sweepAngle,false,anglePaint);
    float textHeight = textPaint.descent() + textPaint.ascent();
String text = progress+"";
textPaint.setTextSize(50);
canvas.drawText(text, 100+150-textPaint.measureText(text)/2, 100+150-textHeight/2, textPaint);
textPaint.setTextSize(20);
String suffixText = "%";
canvas.drawText(suffixText, 100+150+textPaint.measureText(text)/2+12,100+150+textHeight,textPaint);
}
效果:

現在就差繪製下面的文字了,

public class MyProgressView extends View {
    private static final String TAG ="MyProgressView" ;
    private Paint textPaint;//繪製文字的畫筆
private Paint anglePaint;//這是畫弧的畫筆
private Paint bottomTextPaint;
    private int max = 100;
    private int progress;
    private float arcAngle = 360*0.8f;//
public MyProgressView(Context context) {
        this(context,null);
}
    public MyProgressView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
}
    public MyProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
initPainters();
}
    @Override
protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
RectF rectF = new RectF(100,100,400,400);
        float startAngle = (float) (90+0.1*360f);
        float sweepAngle =  progress / (float)max * arcAngle;
anglePaint.setColor(Color.parseColor("#D2691E"));
canvas.drawArc(rectF, startAngle, arcAngle, false, anglePaint);
anglePaint.setColor(Color.parseColor("#9ACD32"));
canvas.drawArc(rectF,startAngle,sweepAngle,false,anglePaint);
        float textHeight = textPaint.descent() + textPaint.ascent();
String text = progress+"";
textPaint.setTextSize(50);
canvas.drawText(text, 100+150-textPaint.measureText(text)/2, 100+150-textHeight/2, textPaint);
textPaint.setTextSize(20);
String suffixText = "%";
canvas.drawText(suffixText, 100+150+textPaint.measureText(text)/2+12,100+150+textHeight,textPaint);
//
String bottomText = "memory";
        float arcBottomHeight = 150 * (float) (1 - Math.cos(36 / 180 * Math.PI));//文字的高度
canvas.drawText(bottomText,100+150-bottomTextPaint.measureText(bottomText)/2,400-arcBottomHeight,bottomTextPaint);
}

    /**
     * 設定進度值,實時更新進度
* @param progress
*/
public void setProgress(int progress){
        this.progress = progress;
        if (this.progress > max) {
            this.progress %= max;
            return;
}
        invalidate();
}
    /**
     * 獲取當前進度值
* @return
*/
public int getProgress(){
        return progress;
}
    private void initPainters() {

        bottomTextPaint = new Paint();
bottomTextPaint.setColor(Color.BLUE);
bottomTextPaint.setTextSize(40);
bottomTextPaint.setStrokeWidth(8);
textPaint = new Paint();
textPaint.setColor(Color.RED);
textPaint.setTextSize(24);//設定文字的大小
textPaint.setAntiAlias(true);
anglePaint = new Paint();
anglePaint.setStrokeWidth(8);
anglePaint.setColor(Color.parseColor("#D2691E"));
anglePaint.setStyle(Paint.Style.STROKE);//設定成空心
anglePaint.setAntiAlias(true);
anglePaint.setStrokeCap(Paint.Cap.ROUND);
}
}
效果:

ok,第二個進度條效果算寫完了,現在還差最後一個效果如下:


分析圖:


程式碼;

package com.example.pbdemo;
import android.content.Context;

            
           

相關推薦

android 圓形進度簡單實現

在網上看了些進度條效果,於是就想寫關於這方面部落格,先看下今天要實現一些進度條的效果圖: 當然要實現這些效果是基於你對canvas類繪製一些圖形是瞭解的,否則估計也不好看懂,我儘量講的詳細點, 先從簡單的畫圓開始一步步把這個效果實現出來,這樣幾乎每個人都能看的懂, 畫圓的

android自定義圓形進度實現動態畫圓效果

自定義圓形進度條效果圖如下:應用場景如動態顯示分數等。 view的自定義屬性如下attr.xml <?xml version="1.0" encoding="UTF-8"?> <resources> <declare-style

Android自定義控制元件NumberCircleProgressBar(圓形進度)的實現

Mode Rotate 實現方式 1.使用unreachedarea的顏色繪製Circle,作為底層; canvas.drawCircle(centerX, centerY,mCircleRadius, mCirclePaint); 2.使用reacherarea的顏色繪製扇形,作為中間層; canvas.

android圓形進度ProgressBar顏色設定

Java程式碼 <ProgressBar        android:id="@+id/loadProgressBar"        android:layout_width="wrap_content"        android:layout_height="wrap_content" 

Android圓形進度-RoundProgressBar

RoundProgressBar public class RoundProgressBar extends View { private Paint mPaint; private int mRoundColor; private int mRo

android進度實現

package com.example.administrator.progress; import android.app.Activity; import android.os.Bundle; i

Android圓形進度

/** * 仿iphone帶進度的進度條,執行緒安全的View,可直接線上程中更新進度 * * @author xiaanming */ public class RoundProgressBar extends View { /**

Android 圓形進度

目錄結構 核心程式碼CicleProgressView.java public class CircleProgressView extends View { /** * 背景顏色 */ private i

進度圓形進度實現

今天通過自定義View來實現一個帶進度的圓形進度條,實現的最終效果如下圖所示: 現在來講一下設計的思路:首先這個進度條可以自定義小圓角矩形的數量、小圓角矩形大小、小圓角矩形的圓角角度、未完成進度時的顏色,完成進度時的顏色、文字大小、文字顏色、圓形半徑,所以

Android學習之路------自定義控制元件,圓形進度簡單實現

簡單介紹 主要是通過自定義一個view類,然後通過操作canvas和paint進行效果的實現 Step 1 新建一個attr.xml,這裡主要是為了自定義我們的控制元件屬性,attr開頭的語句表示控制元件的自定義屬性,在這裡為了實現圓形進度條,定義了一

Android開發自定義控制元件實現一個圓形進度【帶數值和動畫】

實現一個如下圖所示的自定義控制元件,可以直觀地展示某個球隊在某個賽季的積分數和勝場、負場、平局數 首先對畫布進行區域劃分,整個控制元件分上下兩部分 上邊是個大的圓環,圓環中間兩行文字,沒什麼難度,選好圓心座標和半徑後直接繪製即可,繪製文字也是如此。 下部分是三個小的圓弧進

Android 三種常用實現自定義圓形進度 ProgressBar 及demo

           Android 自定義 進度條,一般有三種方式,最早一般使用UI給的圖片使用幀動畫,完成,後面兩種,一種是使用自定義顏色,另外一種是使用帶相近色的圖片加動畫完成。 下面具體 說一下三種方式,推薦使用第二種方式,如果這種達不到效果,或者比較高也可使用第一

Android自定義圓形進度實現程式碼

基本思路是這樣的: 1.首先繪製一個實心圓 2.繪製一個白色實心的正方形,遮住實心圓 3.在圓的中心動態繪製當前進度的百分比字元 4.繪製一個與之前實心圓相同顏色的空心圓 5.逐漸改變當前的百分比 6.根據百分比,逐漸改變正方形的大小,逐漸減小正方形的底部y軸的座標,不斷重繪

Android自定義View——從零開始實現圓形進度

前言:以前老是用別人造的輪子,知其然不知其所以然,有時看懂了別人寫的過多幾個月又忘了,遂來開個坑把一步步實現和思路寫下來,弄成一個系列。由於上班時間不多,爭取一週擼個一到兩篇出來 本篇只著重於思路和實現步驟,裡面用到的一些知識原理不會非常細地拿來講,如

Android進度】三種方式實現自定義圓形進度ProgressBar

總結了3種方法: 1.多張圖片切換 2.自定義顏色 3.旋轉自定義圖片 其它: Android自定義控制元件NumberCircleProgressBar(圓形進度條)的實現:點選開啟連結 橫線帶數字進度條:點選開啟連結

Android 自定義View實現圓形進度 深入理解onDraw和onMeasure及自定義屬性

Android的View類是使用者介面的基礎構件,表示螢幕上的一塊矩形區域,負責這個區域的繪製和事件處理。自定義View的過程主要包括重寫onDraw及onMeasure方法 , 其中onMeasure方法的作用就是計算出自定義View的寬度和高度。這個計算的過

Android原生繪圖進度+簡單自定義屬性程式碼生成器

零、前言 1.感覺切拼字串是個很有意思的事,好的拼接方式可以自動生成一些很實用的東西 2.本文自定義控制元件並不是很高大上的東西,目的在於計錄自定義控制元件的書寫規範與行文流程 3.建議大家自定義控制元件時自定義屬性有自己專屬字首,有利無害,何樂不為 4.本文是根據鴻洋在慕課網上的教程敲的:詳見,自己

Android控制元件之圓形進度

Android-自定義ProgressBar實現圓弧進度條 在之前的專案中用到過這個,感覺還是非常實用的,我實現的是額度的增長. 繼承於ProgressBar實現,保留了Progressbar的特性,原始碼在文尾。

Canvas實現多個圓形進度顯示百分比,並繫結各自的click事件

Canvas實現多個圓形進度條顯示百分比,並繫結各自的click事件 目錄 Canvas實現多個圓形進度條顯示百分比並繫結各自的click事件 目錄 實現效果 製

自定義View實現圓形進度跳轉頁面

效果: //首先在values資料夾下建立一個attrs.xml: ?xml version=“1.0” encoding=“utf-8”?> //佈局: <?xml version="1.0" encoding="utf-8"?>