详解如何让Android UI设计性能更高效

移动开发 Android
本文为一名参加过09年Google IO大会的开发者的一篇把关于移动应用方面的主题不错的PPT改编的文章,对移动应用开发者是很有帮助的。

51CTO编者按:本文为一名参加过09年Google IO大会的开发者的一篇把关于移动应用方面的主题不错的PPT改编的文章,对移动应用开发者是很有帮助的。其实51CTO也有一篇“Android UI”设计官方教程,感兴趣的朋友也可以看一下。

Android在UI优化方面可以从以下五个方面入手:

◆Adapter优化

◆背景和图片优化

◆绘图优化

◆视图和布局优化

◆内存分配优化

Adapter优化

什么是Adapter?

Adapter在Android中占据一个重要的角色,它是数据和UI(View)之间一个重要的纽带。在常见的View(ListView,GridView)等地方都需要用到Adapter。如图1直观的表达了Data、Adapter、View三者的关系。

Adapter、数据、UI三者关系
图1 Adapter、数据、UI三者关系

一、Android中Adapter

Android-Adapter
图2:Android中Adapter类型层级图

由图2我们可以看到在Android中与Adapter有关的所有接口、类的完整层级图。在我们使用过程中可以根据自己的需求实现接口或者继承类进行一定的扩展。比较常用的有 BaseAdapter,ArrayAdapter,SimpleCursorAdapter等。

BaseAdapter是一个抽象类,继承它需要实现较多的方法,所以也就具有较高的灵活性;

ArrayAdapter支持泛型操作,通常需要实现getView方法,特殊情况下(结合数据row id),为了让ui事件相应处理方便点最好重写getItemId;

SimpleCursorAdapter可以适用于简单的纯文字型ListView,它需要Cursor的字段和UI的id对应起来。如需要实现更复杂的UI也可以重写其他方法。

二、一个继承BaseAdapter的类的代码段

 1: /**  
 2:  * 歌曲列表适配器  
 3:  *   
 4:  * @version 2010-11-24 下午05:13:33  
 5:  * @author Hal  
 6:  */  
 7: public class AudioListAdapter extends BaseAdapter {  
 8:    
 9:     private Context mContext;  
10:    
11:     // 歌曲集合  
12:     private ArrayList<Audio> mAudios;  
13:    
14:     public AudioListAdapter(Context mContext, ArrayList<Audio> mAudios) {  
15:         this.mContext = mContext;  
16:         this.mAudios = mAudios;  
17:     }  
18:    
19:     @Override  
20:     public int getCount() {  
21:         return mAudios != null ? mAudios.size() : 0;  
22:     }  
23:    
24:     @Override  
25:     public Object getItem(int position) {  
26:         if ((mAudios != null && mAudios.size() > 0) && (position >= 0 && position < mAudios.size())) {  
27:             return mAudios.get(position);  
28:         }  
29:         return null;  
30:     }  
31:    
32:     /**  
33:      * 如果集合中的对象数据来自数据库,建议此方法返回该对象在数据库中的ID  
34:      */  
35:     @Override  
36:     public long getItemId(int position) {  
37:         if ((mAudios != null && mAudios.size() > 0) && (position >= 0 && position < mAudios.size())) {  
38:             return mAudios.get(position).getId();  
39:         }  
40:         return position;  
41:     }  
42:    
43:     @Override  
44:     public View getView(int position, View convertView, ViewGroup parent) {  
45:         //TODO 返回自定的View  
46:     } 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.

Adapter与View的连接主要依靠getView这个方法返回我们需要的自定义view。ListView是Android app中一个最最最常用的控件了,所以如何让ListView流畅运行,获取良好的用户体验是非常重要的。对ListView优化就是对Adapter中的getView方法进行优化。09年的Google IO大会给出的优化建议如下:

Adapter优化示例代码:

@Override  
public View getView(int position, View convertView, ViewGroup parent) {  
    Log.d("MyAdapter", "Position:" + position + "---"  
            + String.valueOf(System.currentTimeMillis()));  
    ViewHolder holder;  
     if (convertView == null) {  
        final LayoutInflater inflater = (LayoutInflater) mContext  
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
        convertView = inflater.inflate(R.layout.list_item_icon_text, ull);  
        holder = new ViewHolder();  
        holder.icon = (ImageView) convertView.findViewById(R.id.icon);  
        holder.text = (TextView) convertView.findViewById(R.id.text);  
        convertView.setTag(holder);  
    } else {  
        holder = (ViewHolder) convertView.getTag();  
    }  
    holder.icon.setImageResource(R.drawable.icon);  
    holder.text.setText(mData[position]);  
    return convertView;  
}  
   
static class ViewHolder {  
    ImageView icon;  
   
    TextView text;  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.

以上是Google io大会上给出的优化建议,经过尝试ListView确实流畅了许多。

@Override  
public View getView(int position, View convertView, ViewGroup parent) {  
     Log.d("MyAdapter", "Position:" + position + "---"  
             + String.valueOf(System.currentTimeMillis()));  
         final LayoutInflater inflater = (LayoutInflater) mContext  
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);  
        View v = inflater.inflate(R.layout.list_item_icon_text, null);  
         ((ImageView) v.findViewById(R.id.icon)).setImageResource(R.drawable.icon);  
         ((TextView) v.findViewById(R.id.text)).setText(mData[position]);  
        return v;  
 }  
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

以上是不建议的做法!!

不过我们还是要怀疑一下,SO,我们还是来测试对比一下。

测试说明:

大家可以看到在getView的时候我们通过log打印出position和当前系统时间。我们通过初始化1000条数据到Adapter显示到ListView,然后滚动到底部,计算出position=0和position=999时的时间间隔。

测试机子:HTC Magic

测试实录:打开测序,让ListView一直滚动底部。

device

测试结果:

两种情况在操作过程中体验明显不同,在优化的情况下流畅很多很多!

1、优化建议测试结果

12-05 10:44:46.039: DEBUG/MyAdapter(13929): Position:0---1291517086043   
12-05 10:44:46.069: DEBUG/MyAdapter(13929): Position:1---1291517086072   
12-05 10:44:46.079: DEBUG/MyAdapter(13929): Position:2---1291517086085  
 
……  
 
12-05 10:45:04.109: DEBUG/MyAdapter(13929): Position:997---1291517104112   
12-05 10:45:04.129: DEBUG/MyAdapter(13929): Position:998---1291517104135   
12-05 10:45:04.149: DEBUG/MyAdapter(13929): Position:999---1291517104154  
 
耗时:17967  
 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

2、没优化的测试结果

12-05 10:51:42.569: DEBUG/MyAdapter(14131): Position:0---1291517502573   
12-05 10:51:42.589: DEBUG/MyAdapter(14131): Position:1---1291517502590   
12-05 10:51:42.609: DEBUG/MyAdapter(14131): Position:2---1291517502617  
 
……  
 
12-05 10:52:07.079: DEBUG/MyAdapter(14131): Position:998---1291517527082   
12-05 10:52:07.099: DEBUG/MyAdapter(14131): Position:999---1291517527108   
 
耗时:24535  
 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

在1000条记录的情况下就有如此差距,一旦数据nW+,ListView的Item布局更加复杂的时候,优化的作用就更加突出了!

Phone Club——51CTO移动开发线下技术沙龙

活动日期:12月19日
本期主题:Android应用开发技术进阶
地点:创新工场 北京市海淀区北四环西路66号第三极大厦B座18层
演讲讲师:王明礼(创新工场) 范怀宇(网易)

【编辑推荐】

  1. 多图详解 “Android UI”设计官方教程
  2. 多图详解 “Android UI”设计官方教程(二)
  3. 对Android UI实例全解析
  4. 怎样进行Android UI元素设计
  5. Android UI设计大有可为 或可超越iPhone(视频)
责任编辑:张攀 来源: cnblogs
相关推荐

2023-09-12 16:20:04

边缘AI深度学习

2018-05-08 14:58:07

戴尔

2010-10-18 14:59:05

电子政务平台

2015-08-14 10:44:33

HTML5

2015-04-02 12:42:26

HDFS分层存储高效

2019-04-19 08:47:00

前端监控数据

2023-11-24 11:20:04

functoolsPython

2016-06-30 16:54:49

UCloud爱数云计算

2017-11-02 10:23:48

冷热分层存储

2011-07-21 13:52:43

组策略网络打印机

2015-09-30 14:22:44

Qlik数据

2015-12-31 11:57:17

华为eLTE物联网

2011-08-29 09:33:48

2010-12-23 15:55:00

上网行为管理

2018-10-23 15:20:29

SparkShuffleSpark SQL

2024-04-26 07:54:07

ZustandReact状态管理库

2021-12-10 11:46:33

无线网络

2015-03-16 16:56:54

开发技巧应用孤岛PaaS

2023-11-16 08:55:14

CSS前端
点赞
收藏

51CTO技术栈公众号