首先我要说明的是这里“android用户编程技巧”系列的文章中所涉及的技术技巧以及讲述方式不是我本人原创。这些技巧是来自2009年google开发者日(Google Developer Day 2009)上,google公司一位负负责android系统framework层和浏览器开发的一位工程师(很抱歉没有能记住她的名字)的技巧,因为是在开发者大会上演讲是分享的,所以很多人称之为官方的技巧。
当然演讲的具体内容大家可以通过网络轻易得到我也会在后期的文章中给出演讲视频的地址和文档下载地址。我这这里写出来主要是想这样的技术人跟多的知道和使用。过了一年的时间或许这些技巧中有些已经有待更新,那么就让我们一起在这里讨论吧。
重点说演讲中的第一部分——如何使用Adapter。
adapter和listview以及数据源之间的关系
listview相信是大家熟知的一种视图控件了,那么在Adapter相信大家也是一定不会陌生。正如这位是工程师说话Adapter是listview和数据源之间的中间人。关系如图所示。图片是演讲时所用ppt中的图片。
当我们滑动listview的时候每一条数据进入可见区域的时候adapter的getView方法就会被调用,返回代表具体数据的视图。那么当我们的listview中有多条数据的时候(一般都是有多条数据的),getView方法就会反复多次的频繁调用。这样的listview就可以显示很多数据,即成百上千条数据。
那么显而易见,由于getview方法是频繁调用的我们应该经历的在这个方法中尽可能少的产生对象,最大可能大的提高这个方法的工作效率。这样我们的list的更新速度才不至于太慢。
剖析listview
让我们来虚拟一个listview 我们假设这个listview的可见区域中有7个listview,当我们用手指向上滑动一个item的时候,第一条数据就离开了可见区域。在android系统上,为了有效的使用java机制,设立了回收区域。那么离开可见区域的数据就进入了会回收区域,以便于以后再次使用。adpater怎么会对应的标记这个离开可见区域的数据项,adapter同时会生产第八个视图的数据并显示在可见区域。这个就完了listview的一次更新。
简单示例
我们假设需要完成的listview的每一个数据视图如图所示:
它的布局文件如下:
<LinearLayout
xmlns:android=”http://schemas.android.com/apk/res/android”
android:orientation=”horizontal”>
<ImageView android:id=”@+id/icon”
android:layout_width=”48dip”
android:layout_height=”48dip” />
<TextView android:id=”@+id/text”
android:layout_gravity=”center_vertical”
android:layout_width=”0dip”
android:layout_weight=”1.0″
android:layout_height=”wrap_content” />
</LinearLayout>
最简单的方法:
1
public View getView(int pos, View convertView,
2
ViewGroup parent){
3
View item = mInflater.inflate(R.layout.list_item, null);
4
((TextView) item.findViewById(R.id.text)).
5
setText(DATA[pos]);
6
((ImageView) item.findViewButId(R.id.icon)).
7
setImageBitmap((pos & 1) == 1 ? mIcon1 : mIcon2);
8
return item;
9
}
inflate方法每次调用getview方法的时候都会调用,但是我们发现 每一个view都是同样的操作。最主要的是,正如我们前面所说当,一个item视图从可见区域被滑动到不可见区域之后,它会进入会区域,但我们再次让这个item进入可见区域的时候我们完全没有必须有再次调用 inflate方法来展开视图,所以这个部分,我们可以利用converView来做一个判断,当converView是null时,也就是回收区域中么有我们要显示的视图的时候我们才去调用inflate方法展开视图布局。这样我们就可以对代码进行简单有效的优化。
利用convertView回收视图, 效率提高 200%
01
public View getView(int pos, View convertView,
02
ViewGroup parent){
03
if (convertView == null) {
04
convertView = mInflater.inflate(
05
R.layout.list_item, null);
06
}
07
((TextView) convertView.findViewById(R.id.text)).
08
setText(DATA[pos]);
09
((ImageView) convertView.findViewButId(R.id.icon)).
10
setImageBitmap((pos & 1) == 1 ? mIcon1 : mIcon2);
11
return convertView;
12
}
相同,我们会发现findviewbyid这里的计划代码也是每次都要调用,我们是不是可以有一个什么方法,让这些操作也像前面的一样回收起来呢。这个时候我们考虑使用viewholder模式。我们首先写一个静态的类,将每一个item的子视图,一个图片视图和一个文本视图缓存或者说是回收在这个静态类中,这样我们就可以节省一些执行findviewbyid方法的时间。这样我们又一次可以优化代码。
利用ViewHolder模式,效率再次调高50%
ViewHolder静态类:
1
static class ViewHolder {
2
TextView text;
3
ImageView icon;
4
}
getview方法代码如下:
01
public View getView(int pos, View convertView, ViewGroup parent){
02
ViewHolder holder;
03
if (convertView == null) {
04
convertView = mInflater.inflate(R.layout.list_item, null);
05
holder = new ViewHolder();
06
holder.text = (TextView) convertView.findViewById(
07
R.id.text));
08
holder.icon = (ImageView) convertView.findViewButId(
09
R.id.icon));
10
convertView.setTag(holder);
11
} else {
12
holder = (ViewHolder) convertView.getTag();
13
}
14
holder.text.setText(DATA[pos]);
15
holder.icon.setImageBitmap((pos & 1) == 1 ? mIcon1 : mIcon2);
16
return convertView;
17
}
最后呢,这位工程师对这三种方式进行了一个更新数据的比较,用一般的方法每秒更新8个frame,采用回收机制的方法是每秒27个frame,采用ViewHolder模式方法每秒36个frame。
更新效率比较图:
最后,着这次演讲中一个设计了5个模块的编程技巧,如下:
Adapter的使用
图像和背景
更新请求
视图和布局
内存分配
后续我会陆续将其他部分在这里发布,再次申明这些方法是09年google开发者大会分享的,我不知道为什么这些方法按理来说应该早为我们中国开发者所熟知,可是我在很多社区中看多有很多朋友还在找出找这些问题的答案。因此我再次将这些技巧整理发布出来,希望更多的朋友在使用搜索引擎的时候可以找到这些技巧。
- 大小: 18.1 KB
- 大小: 30.1 KB
- 大小: 27.9 KB
分享到:
相关推荐
《基于Android的移动管理...总结,这个基于Android的移动图书管理系统结合了Java编程、数据库管理、网络通信、用户界面设计等多种技术,是一个综合性的开发项目,对于学习和理解Android应用开发具有很高的实践价值。
3. 设计和实现用户界面,包括使用 Layout、Widget、Adapter 等控件。 4. 实现业务逻辑,包括使用 Java 语言编写业务逻辑代码。 5. 测试和调试应用程序,包括使用 Logcat、Debugger 等工具。 6. 发布应用程序,包括将...
7. **UI设计**:使用Android Studio的布局编辑器设计用户界面,包括标题、摘要、发布时间等元素的布局。 8. **事件监听**:为ListView项添加点击事件监听,实现点击后跳转至文章详情页面。 9. **异步处理**:网络...
这些可以通过Android的Animation API、Transition API或Property Animation API来实现,它们可以增加用户界面的动态感和吸引力。 3. **自定义View**:为了实现独特的页面效果,开发者可能需要自定义View或ViewGroup...
- XML布局:理解如何使用LinearLayout、RelativeLayout或ConstraintLayout创建用户界面。 - Java编程:掌握Activity、Fragment的生命周期,以及如何在它们之间进行通信。 - 数据绑定:了解Data Binding库或MVVM...
这个标题暗示了我们可以通过学习这份源码来理解如何在Android平台上构建类似UCWEB的用户界面。 【描述分析】 描述信息简洁明了,"安卓Android源码——仿UCWEB界面源码.zip"与标题一致,表明这是一个专注于Android...
蘑菇街作为一个知名的电商平台,其用户界面设计往往具有较高的交互性和美观性,值得开发者学习和借鉴。 首先,我们看到有两个图片文件,可能是设计图或截图,展示了蘑菇街界面的部分视觉效果。这些图像可以帮助我们...
UCWEB是一款知名的手机浏览器,其简洁、高效的用户界面深受用户喜爱。该源码的目的是帮助开发者掌握如何模仿并实现UCWEB7.4的界面风格,包括启动页、主页面、地址栏、导航栏等关键元素。在实际操作中,开发者将接触...
这个压缩包"安卓Android源码——仿安卓美团界面.rar"提供了一个学习实例,它是一个仿制美团应用界面的项目,适合对Android UI设计和编程有兴趣的开发者进行研究。通过对这个项目的分析,我们可以深入理解Android应用...
在本项目中,我们主要探讨的是如何在Android平台上开发一...通过深入研究这个“安卓Android源码——仿安卓美团界面”的项目,开发者不仅能学习到如何构建复杂的用户界面,还能提升对Android开发流程和最佳实践的理解。
在安卓开发领域,掌握源码分析和应用是提升技术...通过研究这个开源项目,开发者不仅可以学习到Android文件操作的实践技巧,还能掌握UI设计、事件处理、异步编程等方面的知识,进一步提升自己的Android应用开发能力。
在安卓(Android)平台上,开发一个用户界面(UI)对于任何应用程序来说都是至关重要的,因为UI是用户与应用交互的窗口。"安卓Android源码——奇艺高清UI界面源代码.zip"提供了一个深入理解Android UI设计和实现的...
"安卓Android源码——仿乐淘的应用界面源码.zip" 是一个针对Android平台的项目源码包,旨在帮助开发者理解和实现类似乐淘这样的电商应用的用户界面。通过分析这个源码,我们可以深入学习到Android应用设计和开发的多...
本项目“MyAppWeixin”是基于Android平台的源码实现,旨在模仿微信的用户界面和部分功能,为学习Android UI设计和微信交互逻辑的开发者提供了一个很好的参考实例。 首先,我们关注的是UI设计。微信的界面设计简洁且...
这个源码实例主要展示了如何在Android平台上设计和实现一个用户界面(UI)友好的天气预报展示系统。通过学习和理解这段代码,开发者可以了解到如何在Android应用中集成天气数据、创建动态的界面效果以及优化用户体验...
2. **Activity与布局**:在Android应用中,Activity是用户界面的主要组件。2048游戏的主界面应由一个Activity来管理。布局文件通常使用XML编写,定义了屏幕上的各个视图,如TextView(显示分数)、GridView(游戏...
Android使用XML来定义用户界面布局。MyGallery可能使用了LinearLayout、RelativeLayout、GridLayout等布局管理器,或者更先进的ConstraintLayout来组织控件。同时,自定义View和Adapter可能是为了实现个性化的图片...
不过我们可以推测,这个压缩包包含的源代码可能包括了WordPress for Android应用的所有核心组件,如用户界面、数据同步、登录验证、文章编辑和发布等功能的实现。 【标签解析】 "android 安卓"这两个标签进一步确认...
《安卓Android源码——SportsBoards深度解析》 在安卓应用开发领域,深入理解源码是提升技术能力的重要途径。本篇文章将详细探讨SportsBoards项目中的关键知识点,旨在帮助开发者更好地理解和应用Android源码。 ...
Activity是用户界面的主要承载者,Service则负责后台任务,BroadcastReceiver用于监听系统或自定义广播事件,ContentProvider则实现了数据共享和访问控制。 UI布局是应用的外在表现,源码中的XML布局文件揭示了如何...