[原]Android开发优化-Adapter优化
ListView作为Android开发中使用频率最高的一个控件,保证ListView的流畅运行,对用户体验的提高至关重要。Adapter是ListView和数据源之间的中间人,当每条数据进入可见区时,Adapter 的 getView() 会被调用,返回代表具体数据的视图,在成百上千条数据触摸滚动时频繁调用,因此如何优化Adapter是提高ListView性能的关键。
1. 使用ViewHolder模式,重复利用convertView,减少频繁查找
在2009年 Google IO开发者大会中已做说明,看一下使用不同实现方式之间的差距:
Adapter 显示每条数据的 XML 布局文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 | < 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. 最慢最不实用的方式
1 2 3 4 5 6 7 8 9 | public View getView( int position, View convertView, ViewGroup parent) { View item = mInflater.inflate(R.layout.list_item_icon_text, null ); ((TextView) item.findViewById(R.id.text)).setText(DATA[position]); ((ImageView) item.findViewById(R.id.icon)).setImageBitmap( (position & 1 ) == 1 ? mIcon1 : mIcon2); return item; } |
2. 使用 convertView 回收视图, 效率提高 200%
1 2 3 4 5 6 7 8 9 10 11 | public View getView( int position, View convertView, ViewGroup parent) { if (convertView == null ) { convertView = mInflater.inflate(R.layout.item, null ); } ((TextView) convertView.findViewById(R.id.text)).setText(DATA[position]); ((ImageView) convertView.findViewById(R.id.icon)).setImageBitmap( (position & 1 ) == 1 ? mIcon1 : mIcon2); return convertView; } |
3. 使用 ViewHolder 模式, 效率再提高 50%
1 2 3 4 | static class ViewHolder { TextView text; ImageView icon; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public View getView( int pos, View convertView, ViewGroup parent){ ViewHolder holder; if (convertView == null) { convertView = mInflater.inflate(R.layout.list_item, null); holder = new ViewHolder(); holder.text = (TextView) convertView.findViewById(R.id.text)); holder.icon = (ImageView) convertView.findViewButId(R.id.icon)); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.text.setText(DATA[pos]); holder.icon.setImageBitmap((pos & 1) == 1 ? mIcon1 : mIcon2); return convertView; } |
更新率比较如下图:
2. 使用工作线程加载数据,减轻UI主线程负担,使UI主线程只专注于UI绘制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // Using an AsyncTask to load the slow images in a background thread new AsyncTask<ViewHolder, Void, Bitmap>() { private ViewHolder v; @Override protected Bitmap doInBackground(ViewHolder... params) { v = params[ 0 ]; return mFakeImageLoader.getImage(); } @Override protected void onPostExecute(Bitmap result) { super .onPostExecute(result); if (v.position == position) { // If this item hasn't been recycled already, hide the // progress and set and show the image v.progress.setVisibility(View.GONE); v.icon.setVisibility(View.VISIBLE); v.icon.setImageBitmap(result); } } }.execute(holder); |
3. 优化item布局,尽量优化子view布局不被过渡重绘,每一点子view的优化都能提高整体的性能
分类:
android
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架