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的子元素的位置和大小