一般情况下,开发Android应用程序时,不直接使用View和ViewGroup类,而是使用这两个类的子类。显示图片就可以使用ImageView类,。虽然Android提供了很多继承了View类的UI组件,但在实际开发中,出现不满足程序需要的情况时,可以通过继承View类来开发自己的组件。
开发自定义的View组件:
创建一个继承Android.view.View类的View类,并重写构造方法。
根据需要重写相应的方法。
在项目的活动中,创建并实例化自定义View类,并将其添加到布局管理器中。
实现过程:
(1)修改项目的res/layout/main.xml文件,删除默认创建的,组件,然后添加一个帧布局组件,并且设置其背景和id。
修改后的代码:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/mylayout"
>
</FrameLayout>
(2)创建一个名称为UserView的View类,继承Android.view.View类,重写带一个参数Context的构造方法和onDraw()方法。其中,在onDraw()方法中重新绘制Activity窗口的背景。UserView类的关键代码如下:
public class UserView extends View {
public UserView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Paint paint =new Paint();//创建Paint的对象
Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(),
R.drawable.viewback);//根据图片生成位图对象
canvas.drawBitmap(bitmap, 0, 0, paint);//绘制图片
if (bitmap.isRecycled()) {//判断图片是否回收
bitmap.recycle();//强制回收图片
}
}
}
(3)在主活动的OnCreate()方法中,首先获取帧布局管理器,并创建UserView类对象,然后为UserView对象添加触摸事件监听,在触摸事件中重绘View组件,最后将UserView对象添加到布局管理器中,关键代码如下:
FrameLayout frameLayout=(FrameLayout)findViewById(R.id.mylayout);//获取帧布局管理器
final UserView view=new UserView(MainActivity.this);//创建并实例化RabbitView类
//添加触摸事件监听
view.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
view.invalidate();//重绘view组件
return true;
}
});
frameLayout.addView(view);//将view添加到布局管理器中
}
Canvas类
Canvas类就是表示一块画布,你可以在上面画你想画的东西。当然,你还可以设置画布的属性,如画布的颜色/尺寸等。Canvas提供了如下一些方法:
Canvas():创建一个空的画布,可以使用setBitmap()方法来设置绘制的具体画布;
Canvas(Bitmap bitmap):以bitmap对象创建一个画布,则将内容都绘制在bitmap上,bitmap不得为null;
Canvas(GL gl):在绘制3D效果时使用,与OpenGL有关;
drawColor:设置画布的背景色;
setBitmap:设置具体的画布;
clipRect:设置显示区域,即设置裁剪区;
isOpaque:检测是否支持透明;
rotate:旋转画布;
Bitmap android.graphics.BitmapFactory.decodeResource(Resources res, int id)
Synonym for decodeResource(Resources, int, android.graphics.BitmapFactory.Options) with null Options.
Parameters:
res The resources object containing the image data
id The resource id of the image data
Returns:
The decoded bitmap, or null if the image could not be decoded.
invalidate()方法 :
android中实现view的更新有两组方法,一组是invalidate,另一组是postInvalidate,其中前者是在UI线程自身中使用,而后者在非UI线程中使用。
说明:请求重绘View树,即draw()过程,假如视图发生大小没有变化就不会调用layout()过程,并且只绘制那些“需要重绘的”视图,即谁(View的话,只绘制该View ;ViewGroup,则绘制整个ViewGroup)请求invalidate()方法,就绘制该视图。
一般引起invalidate()操作的函数如下:
1、直接调用invalidate()方法,请求重新draw(),但只会绘制调用者本身。
2、setSelection()方法 :请求重新draw(),但只会绘制调用者本身。
3、setVisibility()方法 :
3.1 当View可视状态在INVISIBLE转换VISIBLE时,会间接调用invalidate()方法,继而绘制该View。
3.2当View的可视状态在INVISIBLE/ VISIBLE 转换为GONE状态时,会间接调用requestLayout() 和invalidate方法。
同时,由于整个个View树大小发生了变化,会请求measure()过程以及draw()过程,同样地,只绘制需要“重新绘制”的视图
4 、setEnabled()方法 : 请求重新draw(),但不会重新绘制任何视图包括该调用者本身。
requestLayout()方法 :会导致调用measure()过程 和 layout()过程 。
说明:只是对View树重新布局layout过程包括measure()和layout()过程,不会调用draw()过程,但不会重新绘制任何视图包括该调用者本身。
5、requestFocus()函数说明:
说明:请求View树的draw()过程,但只绘制“需要重绘”的视图。