Android提供了一个功能强大的UI组件模型,基于丰富的布局类View和ViewGroup。我们这章就是基于View和ViewGroup派生的子类开始来讲怎样建立自己UI。
Android系统提供了部分可用的Widget,包括Button, TextView, EditText, ListView, CheckBox, RadioButton, Gallery, Spinner,还有一些用于专门用途的,包括AutoCompleteTextView, ImageSwitcher, 和TextSwitcher,另外也有些关于布局的LinearLayout,FrameLayout, RelativeLayout(Common Layout Objects)等等。
如果这些系统内置Widget或者布局View不能满足需求,我们可以建立我们自己的View子类,来实现自己的Widget和Layout。
那如何创建呢?下面是创建View子类完全自绘WIDGET的最基本步骤:
1. 创建自己的类,必须继承View。里面有三个构造函数,一个参数的构造函数主要是让使用者能动态建立,而两个参数的构造函数则是用于XML配置的
2. 重载一些父类的带On方法,比如onDraw(),onMeasure()和onKeyDown()等。其中onDraw和onMeasure()是必须重载 的,onDraw主要是从父类传递Canvas过来,能让你定制自己的2D组件,onMeasure则是定制你组件的大小,在之中你必须得 调用setMeasuredDimension()
。
3. 在你的程序Activity中使用你扩展的类
下面是示例程序:
在Activity中的程序使用Widget
先定义attr.xml,定义WIDGET的一些属性
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="OwnButton"> <attr name="textColor" format="color"/> <attr name="textSize" format="dimension"/> </declare-styleable> </resources>
然后建立自己的Widget(OwnButton):
package com.OwnWidget.OwnButton; import com.OwnWidget.R; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.Rect; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class OwnButton extends View { private Rect mClientRect = null; private Paint mPaint = null; private String mStr; private int mTag = 0; TypedArray mArray; private void initDraw() { mClientRect = new Rect(); mPaint = new Paint(); mStr = "JackLam"; mClientRect.left = this.getLeft(); mClientRect.top = this.getTop(); mClientRect.right = mClientRect.left + 100; mClientRect.bottom = mClientRect.top + 100; mTag = 0; } // 用于自己创建 public OwnButton(Context context) { super(context); initDraw(); } //用于RESOURCE public OwnButton(Context context, AttributeSet attrs) { super(context, attrs); //TypedArray是一个用来存放由context.obtainStyledAttributes获得的属性的数组 //在使用完成后,一定要调用recycle方法 //属性的名称是styleable中的名称+“_”+属性名称 mArray = context.obtainStyledAttributes(attrs, R.styleable.OwnButton); initDraw(); mArray.recycle(); //一定要调用,否则这次的设定会对下次的使用造成影响 } @Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) { setMeasuredDimension(mClientRect.right - mClientRect.left, mClientRect.bottom - mClientRect.top);//must called,default 100 * 100 in android system } @Override protected void onLayout (boolean changed, int left, int top, int right, int bottom) { } @Override protected void onDraw (Canvas canvas) { Rect r = new Rect(); this.getGlobalVisibleRect(r); mPaint.setColor(Color.GREEN); canvas.drawRect(mClientRect, mPaint); mPaint.setTextAlign(Align.CENTER); mPaint.setColor(Color.BLACK); canvas.drawText(mStr, mClientRect.left + r.left, mClientRect.top + r.top, mPaint); } @Override public boolean onTouchEvent (MotionEvent event) { switch(event.getAction()) { case MotionEvent.ACTION_DOWN: if(mTag == 0) { mStr = "Love"; mTag++; } else if(mTag == 1) { mStr = "Elaine"; mTag++; } else if(mTag == 2) { mStr = "Love"; mTag++; } else { mStr = "JackLam"; mTag = 0; } this.invalidate(); break; case MotionEvent.ACTION_UP: break; default: break; } return super.onTouchEvent(event); } }
接着就可以在Activity中使用自己组建的Widget,下面我们用xml的形式来使用。
在layout的main.xml中增加Widget
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> <com.OwnWidget.OwnButton.OwnButton android:id="@+id/widget_myButton" android:layout_width = "wrap_content" android:layout_height = "wrap_content"> </com.OwnWidget.OwnButton.OwnButton> </LinearLayout>
然后在Activity中就可以使用了
package com.OwnWidget; import com.OwnWidget.OwnButton.OwnButton; import android.app.Activity; import android.os.Bundle; import android.widget.LinearLayout; public class OwnWidget extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /*LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); OwnButton btn = new OwnButton(this); layout.addView(btn); setContentView(layout);*/ setContentView(R.layout.main); } }
当然,也可以动态创建WIDGET,在Activity的注释代码就是动态创建的方式,只要把setContentView(R.layout.main);注释掉。
下面一章将会介绍另一种自绘方式,这种方式利用的原有的Widget,将原有的Widget组合起来形成自己的Widget(如由Edit和Button等组成的下拉列表框)。