`

Android中UI(View)的刷新

阅读更多

看了很多资料,翻啊翻啊,似乎有些了解了。

Android中对View的更新有很多种方式,使用时要区分不同的应用场合。我感觉最要紧的是分清:多线程和双缓冲的使用情况。


现在可以尝试理解下面的模拟场景:

        两个人:一对夫妻,老公上班,老婆在家,现在他们都要吃饭。

     “不使用多线程和双缓冲”的情况是:老公在公司吃,老婆在家吃,互不干扰,吃就是了。

     “使用多线程和不使用双缓冲”的情况是:老婆做好饭,另外让人送一份到公司,老公收到饭就可以吃了。

     “使用多线程和使用双缓冲”的情况是:老婆做好饭,等老公回家一起吃。


1.不使用多线程和双缓冲

     这种情况最简单了,一般只是希望在View发生改变时对UI进行重绘。你只需在Activity中显式地调用View对象中的invalidate()方法即可。系统会自动调用 View的onDraw()方法。


2.使用多线程和不使用双缓冲

     这种情况需要开启新的线程,新开的线程就不好访问View对象了。强行访问的话会报:android.view.ViewRoot$CalledFromWrongThreadException:Only the original thread that created a view hierarchy can touch its views.

     这时候你需要创建一个继承了android.os.Handler的子类,并重写handleMessage(Message msg)方法。android.os.Handler是能发送和处理消息的,你需要在Activity中发出更新UI的消息,然后再你的Handler(可以使用匿名内部类)中处理消息(因为匿名内部类可以访问父类变量, 你可以直接调用View对象中的invalidate()方法 )。也就是说:在新线程创建并发送一个Message,然后再主线程中捕获、处理该消息。

 

/**
 * 要在Activity中开启一个用于更新的线程
 * timeViewHandler 继承自Handler,用于处理和发送消息
 * MSG_UPDATE 是自定义的一个int常量,用于区分消息类型,可自由取值。
 */
new Thread(new Runnable() {
	@Override
	public void run() {
		while(true){
			try {
				timeViewHandler.sendMessage(Message.obtain(timeViewHandler, MSG_UPDATE));
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			} 
		}
	}
}).start();
 
/**
 * Handler示例,用于刷新时间
 * DateHelper是我自己写的日期格式化工具哦
 * @author Dreamworker
 *
 */
public class TimeViewHandler extends Handler {
	private TextView timeView;
	
	public TextView getTimeView() {
		return timeView;
	}

	public void setTimeView(TextView timeView) {
		this.timeView = timeView;
	}

	public TimeViewHandler(TextView timeView) {
		super();
		this.timeView = timeView;
	}

	@Override
	public void handleMessage(Message msg) {
		switch (msg.what) {
			case MSG_UPDATE:
				timeView.setText(DateHelper.getNow("kk:mm:ss"));
				timeView.invalidate();
				break;
		}
		super.handleMessage(msg);
	}
	
}
 


3.使用多线程和双缓冲

    Android中SurfaceView是View的子类,她同时也实现了双缓冲。你可以定义一个她的子类并实现SurfaceHolder.Callback接口。由于实现SurfaceHolder.Callback接口,新线程就不需要android.os.Handler帮忙了。SurfaceHolder中lockCanvas()方法可以锁定画布,绘制玩新的图像后调用unlockCanvasAndPost(canvas)解锁(显示),还是比较方便得。

/**
* SurfaceView使用示例,TouchDrawView主要完成屏幕的指尖绘画
* TouchDrawListener是我自己写的监听器,就不妨碍大家视线了。
*/
public class TouchDrawView extends SurfaceView implements SurfaceHolder.Callback{
	private SurfaceHolder holder;
	private TouchDrawListener listener;

	public TouchDrawListener getListener() {
		return listener;
	}

	public void setListener(TouchDrawListener listener) {
		this.listener = listener;
	}

	public TouchDrawView(Context context) {
		super(context);
		holder = getHolder();
		holder.addCallback(this);
		listener = new TouchDrawListener(holder);
		listener.setShape(TouchDrawListener.SHAPE_LINE);
		listener.setShape_style(TouchDrawListener.SHAPE_STYLE_FILL);
		this.setOnTouchListener(listener);//设置屏幕事件监听器
		this.setLongClickable(true);//不设置将无法捕捉onFling()事件
		setFocusable(true);//设置键盘焦点
		setFocusableInTouchMode(true);//设置触摸屏焦点
	}
	
	public TouchDrawView(Context context, AttributeSet as) {
		this(context);
	}

	@Override
	protected void onDraw(Canvas canvas) {	

	}
	
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {

                 //关键部分
		Canvas canvas = holder.lockCanvas(null);//获取画布  
		canvas.drawColor(Color.WHITE);//白色背景
		holder.unlockCanvasAndPost(canvas);//解锁画布,提交画好的图像  
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		
	}
}
 

 

8
0
分享到:
评论

相关推荐

    android ui界面时间刷新

    在Android应用开发中,UI界面的时间刷新是一个常见的需求,特别是在显示实时信息如系统时间、倒计时或计时器等场景。本篇文章将深入探讨如何使用Handler机制来实现在Android UI界面上对系统时间的实时更新。 ...

    android自定义view之刷新验证码

    总的来说,自定义View在Android开发中具有广泛的应用,通过掌握`onMeasure()`和`onDraw()`方法,我们可以创建出各种复杂的UI组件,如这个案例中的可刷新验证码显示。在实践过程中,不断优化代码和提高用户体验,是...

    Android UI试练 微信UIDemo

    在Android中,UI主要由布局(Layouts)和视图(Views)组成。布局管理器如线性布局(LinearLayout)、相对布局(RelativeLayout)、帧布局(FrameLayout)和网格布局(GridLayout)等,负责组织和定位屏幕上的各个...

    Android所有UI控件

    以上只是Android UI控件的一小部分,实际开发中还有更多如DatePicker、TimePicker、ToggleButton等控件,以及自定义View的实现。通过熟练掌握这些控件及其属性,开发者可以创建出丰富多样的用户界面,提升用户体验。...

    Android-UI.rar_android_android ui

    在Android开发中,UI(User Interface)设计是至关重要的,因为它直接影响到用户的体验和应用程序的吸引力。本资源“Android-UI.rar”包含了对Android平台上基本视图组件的深入讲解,帮助开发者更好地理解和创建用户...

    Android UI组件实例集合

    GifView 是一个为了解决android中现在没有直接显示gif的view,只能通过mediaplay来显示这个问题的项目,其用法和 ImageView一样,支持gif图片 使用方法:1-把GifView.jar加入你的项目。2-在xml中配置GifView的基本...

    androidUI典型例子

    这个"androidUI典型例子"是基于模仿奇艺客户端,旨在帮助开发者掌握Android UI设计的基本原则和技巧。下面,我们将深入探讨这个主题,并结合"qiyi_UIPlayHD"这个压缩包中的文件,解析相关的知识点。 1. **布局管理...

    android UI 特效集合

    开发者可以利用Android的`View`和`ViewGroup`子类来创建自定义UI组件,实现独特的设计效果。例如,自定义形状、绘制复杂图形、甚至实现3D视图。 7. **状态栏和导航栏透明化**: 自Android 5.0起,可以使用`...

    Android自定义View实现转盘旋转的效果

    在Android中,自定义 View 是一种非常重要的技术,可以满足开发者的个性化需求。通过继承 View 类,并重写构造函数和 onDraw() 函数,可以实现自定义的 View。onDraw 函数是 View 的一个关键函数,在界面刷新时会被...

    android模仿易信UI布局效果源码

    在Android开发中,模仿流行的移动应用UI布局是提升用户体验和设计水平的重要步骤。易信,作为一款在中国广受欢迎的即时通讯应用,其简洁而高效的设计风格深受用户喜爱。本源码项目专注于重现易信的UI布局,帮助...

    Android 斗地主 UI+逻辑

    - **UI绘制优化**:减少无效的View刷新,利用ViewStub、RecyclerView等优化UI加载和滚动性能。 7. **测试与调试**: - 单元测试:针对游戏逻辑编写单元测试用例,确保算法的正确性。 - 性能测试:检查应用在不同...

    Android-自定义下拉刷新的RecylcerView

    总的来说,自定义下拉刷新的RecyclerView涉及到了Android UI组件的高级用法,包括事件监听、动画制作以及数据管理。掌握这些技能将使你在Android开发中更加游刃有余。实践这些知识,你将能够创建出更加交互性和用户...

    Android-UI-design.rar_android_android ui

    除了GridView,Android还提供了许多其他布局和控件,如RecyclerView(取代ListView,性能更优)、SwipeRefreshLayout(下拉刷新)、FloatingActionButton(浮动操作按钮)等,这些都极大地丰富了UI设计的可能性。...

    Android listView下拉刷新上拉刷新带阻尼效果-IT计算机-毕业设计.zip

    这个"Android listView下拉刷新上拉刷新带阻尼效果"的源码Demo是几年前的一个示例,旨在帮助学生理解和实现Android应用中的下拉刷新和上拉加载更多功能,同时加入了阻尼效果,提升用户体验。阻尼效果是指在用户滑动...

    老罗Android开发视频教程 (android常用UI编程) 26-33集源码

    在本资源中,"老罗Android开发视频教程 (android常用UI编程) 26-33集源码.zip"是一个包含Android应用开发教学内容的压缩文件。老罗,可能指的是知名的技术讲师罗永浩,以其通俗易懂的讲解风格而闻名。这个教程聚焦于...

    Android自定义上拉加载下拉刷新控件

    在Android开发中,上拉加载和下拉刷新是常见的组件功能,用于提升用户体验,使得用户在滚动列表到顶部时能够方便地获取更多数据,而在滚动到底部时加载更多内容。本示例“Android自定义上拉加载下拉刷新控件”提供了...

    Android自定义控件下拉刷新实例代码

    `ImageView`通常用于显示一个箭头图标,表示当前状态是待刷新(如上拉)或刷新中(如旋转)。`ProgressBar`则在刷新过程中显示,提示用户数据正在加载。 ```xml android:id="@+id/arrow" android:layout_width=...

    Android线程中操作UI界面的方法

    本文将详细介绍四种常见的在Android线程中操作UI界面的方法:使用Handler、View.post(Runnable)、Activity.runOnUiThread(Runnable)以及AsyncTask。 ### 1. 使用Handler **原理**: `Handler`机制是Android中处理...

    Android实现支持所有View的通用的下拉刷新控件

    1. **状态管理**:下拉刷新有多个状态,包括Reset(初始状态)、Pull(下拉中)、Refreshing(刷新中)、Completed(刷新完成)和Reset(再次回到初始状态)。我们需要管理这些状态,确保在不同状态下正确地更新UI和...

    android 异步显示View

    在Android开发中,异步加载View是一个常见的需求,特别是在处理大量数据或者网络请求时,为了保证用户界面的流畅性,我们需要将耗时的操作放在后台执行,然后在主线程更新UI。这篇博客“android 异步显示View”可能...

Global site tag (gtag.js) - Google Analytics