您的位置:首页 > 移动开发 > Android开发

android 自定义下载进度条

2013-04-18 12:45 253 查看
继承view实现下载进度条,大家可以参考修改出更好的实现方式,欢迎指正,下面是源码和截图:




1.测试代码:

DownloadProgressBar dpb;
    synchronized void updateUIData(float rate){
        dpb.setProgress(rate);
    }

    void test(){
        dpb=new DownloadProgressBar(this);
        dpb.setWH(100, 4);
        new Thread(new Runnable() {
            int rate = 0;
            @Override
            public void run() {
                while(true){
                    try {
                        if(rate>100){ 
                            break;
                        }
                        myHandler.post(new Runnable() {  //用handler在线程中刷新数据
                            @Override
                            public void run() {
                                Log.i(TAG,"####@@@@rate:"+rate);

                                if(rate == 2){
                                    rate+=2;
                                }else if(rate ==10){
                                    rate+=10;
                                }else if(rate ==20){
                                    rate+=10;
                                }else if(rate ==50){
                                    rate+=20;
                                }else{
                                    rate++;
                                }
                                updateUIData(rate);
                            }
                        });
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
}

2.进度条源码

1>首先设置进度条的宽和高,代码里设定宽度应该为100的整数倍,不然进度条显示的数据并不准确。
2>文件下载的话,可以用上诉例子替换成不停的读以下载的文件大小,然后根据文件总大小得到相对比例,调用updateUIData(rate)刷新ui




import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class DownloadProgressBar extends View{
    private static final String TAG="DownloadProgressBar";

    Context cxt;

    public DownloadProgressBar(Context context) {
        this(context, null);
    }

    public DownloadProgressBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        cxt = context;
        this.setBackgroundResource(R.drawable.jdt02);
        bitmap =BitmapFactory.decodeResource(cxt.getResources(), R.drawable.jdt03);
        mCanvas = new Canvas();
        mpaint = new Paint();
    }

    private int w,h;

    /**
     * 设置进度条的宽高
     * 
     * @param w  
     *          宽
     * @param h
     *          高
     * */
    public void setWH(int w,int h){
        this.w= w;
        this.h=h;
    }

    float rate ;
    float rate_t;
    /**
     * 设置进度比例
     * 
     * @param r 
     *          当前占的比例值
     * */
    public void setProgress(float r){
        this.rate_t = w/100*r;   //(w/100)这里假定以w为100的整数倍
        invalidate((int)rate,0,w,h);
        //invalidate();
    }

    public void clearProgress(){
        rate = 0;
    }

    Canvas mCanvas;
    Paint mpaint;
    Bitmap bitmap;  //一个像素宽的绿色小图片

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
            while(rate<=rate_t){
                for(int i=0;i<w/100;i++){ 
                    Log.i(TAG,"rate:"+rate+",rate_t:"+rate_t);
                    canvas.drawBitmap(bitmap, rate++, 0, null);
                }
            }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        setMeasuredDimension(w, h);
    }
}








3.进度条改进版源码

前面代码出现的问题:

1.每次刷新因为只刷新部分区域,导致按键事件的时候,因为会重新刷新ui,而默认是invalidate()全刷新,导致前面部分的进度没有了

而如果用全部刷新来画每个像素的话,是非常消耗系统资源的,这里简单算下:

a>如果这里用的图片像素宽度是1px的话,而进度条的宽度为400,则
每次ondraw都从0开始画,drawCount = 1+2+3+4+...+400=(1+400)*400/2=80200;




import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;

public class DownloadProgressBar extends View{
    private static final String TAG="DownloadProgressBar";

    Context cxt;

    public DownloadProgressBar(Context context) {
        this(context, null);
    }

    public DownloadProgressBar(Context context, AttributeSet attrs) {
        super(context, attrs);
        cxt = context;
        this.setBackgroundResource(R.drawable.bar_01);
        if(bitmap!=null){
            bitmap.recycle();
        }
        bitmap =BitmapFactory.decodeResource(cxt.getResources(), R.drawable.bar_04);  //和背景大小一致的全绿色图片
        mCanvas = new Canvas();
        mpaint = new Paint();
    }

    private int w,h;

    /**
     * 设置进度条的宽高
     * 
     * @param w  
     *          宽
     * @param h
     *          高
     * */
    public void setWH(int w,int h){
        this.w= w;
        this.h=h;
    }

    float rate = 0;
    float rate_t;

    /**
     * 设置进度比例
     * 
     * @param r 
     *          当前占的比例值
     * */
    public void setProgress(float r){
        if(r>99){
            this.setBackgroundResource(R.drawable.bar_04);
            return;
        }
        this.rate_t = w/100*r;
        //Log.i(TAG,"setProgress:rate="+rate+",rate_t:"+rate_t);
        //invalidate((int)rate,0,w,h);
        invalidate();
    }

    public void clearProgress(){
        rate = 0;
    }

    Canvas mCanvas;
    Paint mpaint;
    Bitmap bitmap;

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
//          while(rate<=rate_t){ 
//              for(int i=0;i<w/100;i++){
//                  //Log.i(TAG,"rate:"+rate+",rate_t:"+rate_t);
//                  canvas.drawBitmap(bitmap, rate++, 0, null);
//              }
//          }

        clipDraw(canvas);
    }

    void clipDraw(Canvas canvas){   //用剪切区域来显示进度条,减少画单个像素的次数
        canvas.save();
        canvas.clipRect(0,0,rate_t, h);
        canvas.drawBitmap(bitmap,0, 0, null);
        canvas.restore();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        setMeasuredDimension(w, h);
    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: