自定义ProcessBar

android与其他GUI应用开发一样,也提供了自定义控件的定制。本文中给出一个自定义processbar的例子,如下:

例子中,控件能够定义进度条已实现和未实现的颜色属性,并且用asynctask以每秒一格的速度刷新。

1. 在values下增加attr.xml,定义MyProcessBar的属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyProcessbar">  
        <attr name="color1" format="color"></attr>  
        <attr name="color2" format="color"></attr>  
    </declare-styleable>   
</resources>

 2. 实现自定义的MyProcessBar类

public class MyProcessbar extends View {
    private Paint mPaint;
    
    private int  current = 0;
    private int  end     = 10;
    private int  color1;
    private int  color2;

    public MyProcessbar(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyProcessbar);  
        color1 = a.getColor(R.styleable.MyProcessbar_color1,0); 
        color2 = a.getColor(R.styleable.MyProcessbar_color2,0); 
        
        a.recycle();
    }

    public MyProcessbar(Context context) {
        super(context);
        mPaint = new Paint();
    }

    //用以更新ProcessBar
    public void setCurAndEnd(int cur, int end){
        current = cur;
        end     = end;
        invalidate();
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
                
        mPaint.setStyle(Style.FILL);
        mPaint.setColor(color1);
        
        for(int i = 0; i < end; i++){
            if(i < current){
                mPaint.setColor(color1);
            }else{
                mPaint.setColor(color2);
            }
            
            canvas.drawRect(new Rect(10 + (25*i),
                    10, 
                    20 + (25*i), 
                    40), mPaint);
        }
    }
}

 3. 在layout中使用该自定义控件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:MyProcessbar="http://schemas.android.com/apk/res/com.example.widget15"
    xmlns:tools="http://schemas.android.com/tools"
    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=".MainActivity" >

    <com.example.widget15.MyProcessbar 
        android:id="@+id/myprocess"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        MyProcessbar:color1="#ff0000"
        MyProcessbar:color2="#00ff00"/>

</RelativeLayout>

 4. 在Activity中启动一个异步任务更新该控件,异步任务实现如下:

public class MyTask extends AsyncTask<String, Integer, String> {
    
    private MyProcessbar mprogressbar;
    
    public MyTask(MyProcessbar mprogressbar) {
        super();
        this.mprogressbar = mprogressbar;
    }
    
    @Override
    protected String doInBackground(String... params) {
        int i = 0;
        for(i = 0; i < 10; i++){
            try {
                Thread.sleep(1000);
                publishProgress(i);  
                
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
        return i + "&" + params[0];
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        mprogressbar.setCurAndEnd(values[0], 10);
    }
}

备注:

自定义控件此例中主要用到onDraw方法,其他主要接口还有onMeasure和onLayout,

1. onMeasure 属于View的方法,用来测量自己和内容的来确定宽度和高度 ,view的measure方法体中会调用onMeasure

2. onLayout 属于ViewGroup的方法,用来为当前ViewGroup的子元素的位置和大小

 

posted @ 2013-03-22 16:59  Fredric_2013  阅读(355)  评论(0编辑  收藏  举报