android view 的刷新方式
2014-01-11 17:22
405 查看
Android中对View的更新有很多种方式,使用时要区分不同的应用场合。我感觉最要紧的是分清:多线程和双缓冲的使用情况。
1.不使用多线程和双缓冲
这种情况最简单了,一般只是希望在View发生改变时对UI进行重绘。你只需在Activity中显式地调用View对象中的invalidate()方法即可。系统会自动调用View的onDraw()方法。
2.使用多线程和不使用双缓冲
这种情况需要开启新的线程,新开的线程就不好访问View对象了。强行访问的话会报:android.view.ViewRoot$CalledFromWrongThreadException:Onlythe
original thread that created a view hierarchy can touch itsviews.
这时候你需要创建一个继承了android.os.Handler的子类,并重写handleMessage(Messagemsg)方法。android.os.Handler是能发送和处理消息的,你需要在Activity中发出更新UI的消息,然后再你的Handler(可以使用匿名内部类)中处理消息(因为匿名内部类可以访问父类变量,你可以直接调用View对象中的invalidate()方法)。也就是说:在新线程创建并发送一个Message,然后再主线程中捕获、处理该消息。
3.使用多线程和双缓冲
Android中SurfaceView是View的子类,她同时也实现了双缓冲。你可以定义一个她的子类并实现SurfaceHolder.Callback接口。由于实现SurfaceHolder.Callback接口,新线程就不需要android.os.Handler帮忙了。SurfaceHolder中lockCanvas()方法可以锁定画布,绘制玩新的图像后调用unlockCanvasAndPost(canvas)解锁(显示),还是比较方便得。
。invalidate()函数重绘
public class PuzzleView extends View {
@Override
protected void onDraw(Canvascanvas) {
...
}
@Override
public booleanonTouchEvent(MotionEvent event) {
invalidate();
//处理逻辑
invalidate(); //刷
}
}
复制代码
当调用线程处于空闲状态时,会调用onDraw,刷新界面,也就是说,该函数仅是标记当前界面过期,并不直接负责刷新界面()
public class PuzzleView extends SurfaceView implementsSurfaceHolder.Callback{
private SurfaceHoldersurfaceHolder;
public PuzzleView(Contextcontext){
//....
surfaceHolder =this.getHolder();//获取holder
surfaceHolder.addCallback(this);
}
protected void paint(Canvascanvas) {
//这里的代码跟继承View时OnDraw中一样
}
public void repaint(){
Canvas c = null;
try {
c =surfaceHolder.lockCanvas();
paint(c);
} finally {
if (c !=null) {
surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
1.不使用多线程和双缓冲
这种情况最简单了,一般只是希望在View发生改变时对UI进行重绘。你只需在Activity中显式地调用View对象中的invalidate()方法即可。系统会自动调用View的onDraw()方法。
2.使用多线程和不使用双缓冲
这种情况需要开启新的线程,新开的线程就不好访问View对象了。强行访问的话会报:android.view.ViewRoot$CalledFromWrongThreadException:Onlythe
original thread that created a view hierarchy can touch itsviews.
这时候你需要创建一个继承了android.os.Handler的子类,并重写handleMessage(Messagemsg)方法。android.os.Handler是能发送和处理消息的,你需要在Activity中发出更新UI的消息,然后再你的Handler(可以使用匿名内部类)中处理消息(因为匿名内部类可以访问父类变量,你可以直接调用View对象中的invalidate()方法)。也就是说:在新线程创建并发送一个Message,然后再主线程中捕获、处理该消息。
3.使用多线程和双缓冲
Android中SurfaceView是View的子类,她同时也实现了双缓冲。你可以定义一个她的子类并实现SurfaceHolder.Callback接口。由于实现SurfaceHolder.Callback接口,新线程就不需要android.os.Handler帮忙了。SurfaceHolder中lockCanvas()方法可以锁定画布,绘制玩新的图像后调用unlockCanvasAndPost(canvas)解锁(显示),还是比较方便得。
。invalidate()函数重绘
public class PuzzleView extends View {
@Override
protected void onDraw(Canvascanvas) {
...
}
@Override
public booleanonTouchEvent(MotionEvent event) {
invalidate();
//处理逻辑
invalidate(); //刷
}
}
复制代码
当调用线程处于空闲状态时,会调用onDraw,刷新界面,也就是说,该函数仅是标记当前界面过期,并不直接负责刷新界面()
public class PuzzleView extends SurfaceView implementsSurfaceHolder.Callback{
private SurfaceHoldersurfaceHolder;
public PuzzleView(Contextcontext){
//....
surfaceHolder =this.getHolder();//获取holder
surfaceHolder.addCallback(this);
}
protected void paint(Canvascanvas) {
//这里的代码跟继承View时OnDraw中一样
}
public void repaint(){
Canvas c = null;
try {
c =surfaceHolder.lockCanvas();
paint(c);
} finally {
if (c !=null) {
surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
相关文章推荐
- Android RecyclerView 真正的布局刷新的正确方式
- [Android 小知识点] textview 设置下划线的两种方式
- 【Android UI】Android开发之View的几种布局方式及实践
- Android WebView的前进、后退、与刷新
- Android自定义View的三种实现方式
- Android开发RecyclerView刷新后item里面控件动画
- android开发游记:RecycleView 实现复杂首页布局三种方式
- Android -- ViewRoot,关于子线程刷新UI
- [转]Android SurfaceView 绘图覆盖刷新及脏矩形刷新方法
- android:RecyclerView局部刷新那点事
- Android 开发之旅:view的几种布局方式及实践
- Android学习 (十) 让TextView里面文字居中的方式
- [置顶] Android 仿微信刷新旋转小风车 自定义view
- Android滑动冲突解决方式(下拉刷新上拉加载更多,适配RecyclerView/ListView/ScrollView)
- 安卓选择器类库AndroidPicker、定时器类库CountdownView、上拉刷新加载更多的EasyRecyclerView
- Android XRcyclerView刷新,加载更多
- Android cmwap网络方式下使用 webview
- Android自定义View之双表头表格(表头不动,EditView和TextView两种方式)
- Android开发之View的几种布局方式及实践
- Android SurfaceView 绘图覆盖刷新及脏矩形刷新方法