博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android中ListView的用法及优化
阅读量:5325 次
发布时间:2019-06-14

本文共 4344 字,大约阅读时间需要 14 分钟。

一、ListView的基本用法

列表的显示需要三个元素:

1. ListView:用来展示列表的View。

2. Adapter适配器:是ListView界面与数据之间的桥梁;即用来把数据映射到ListView上的中介;当列表里的每一项显示到页面时,都会调用Adapter的getView方法返回一个View。

3. 数据:具体的将被映射的字符串、图片或基本组件等。

根据列表适配器的类型,可分为三种:ArrayAdapter,SimpleAdapter和CursorAdapter。其中ArrayAdapter最为简单,只能展示一行字。SimpleAdapter可用于显示自定义的复杂布局文件。SimpleCursorAdapter可以认为是SimpleAdapter对数据库的简单结合,可以方便的把数据库的内容以列表的形式展示出来。SimpleAdapter虽说已经可以满足大多数情况的需要,但还不够灵活,用SimpleAdapter显示的每一行布局都是相同的,不能有特殊情况。因此如果希望可以扩展ListView的显示特性,比如使一些行布局发生变化,或者添加Button控件的响应等,这时候就要自己去实现一个BaseAdapter,通过其getView方法为每一行返回特定的布局形式或者视图。例如

系统要绘制ListView,首先用getCount()函数得到要绘制的列表的长度,然后开始绘制第一行,如何绘制呢?调用getView()函数。在这个函数里首先获得一个View(如果是一个简单的显示则是View,如果是一个自定义的里面包含较多控件的时候它其实是一个ViewGroup),然后再实例化并设置各个组件及其数据内容并显示它。绘制完这行后,依此再绘制完。

二、ListView加载数据的基本原理

ListView针对每个item,要求Adapter返回一个视图(getView),即ListView在开始绘制时,系统首先调用getCount()函数,根据他的返回值得到ListView的长度,然后根据该长度,调用getView()一行一行的绘制ListView的每一项。如果getCount()返回值是0的话,列表一行都不会显示,如果返回1,就只显示一行;返回几则显示几行。如果我们有成千上万的item要显示怎么办呢?为每个item创建一个新的View?这是不可能的!实际上Android早就缓存了这些视图;Android中有个Recycler的构件。只有可见的项目存在内存中,其他的在Recycler中。

三、ListView的优化

list.xml

1. 最简单的方法,最慢且最不实用。

1 @Override 2     public View getView(int position, View convertView, ViewGroup parent) { 3        // TODO Auto-generated method stub 4        //找到R.layout.list布局文件 5        layout_Adapter = (LinearLayout)this.layoutInflater.inflate(R.layout.list, null); 6        imageView = (ImageView)layout_Adapter.findViewById(R.id.imageView1); 7        textView = (TextView)layout_Adapter.findViewById(R.id.textView1); 8        imageView.setImageResource(R.drawable.icon); 9        textView.setText(title[position]);10        return layout_Adapter;11     }

2. View的重用。View的每次创建都是比较耗时的,利用convertview回收视图;即对于getview方法传入的convertView做 != null的判断;这样系统将会少创建很多View,性能得到了很大的提升。

1 @Override 2     public View getView(int position, View convertView, ViewGroup parent) { 3        // TODO Auto-generated method stub 4        if(convertView == null){ 5            convertView = (LinearLayout)this.layoutInflater.inflate(R.layout.list, null); 6        } 7        imageView = (ImageView)convertView.findViewById(R.id.imageView1); 8        textView = (TextView)convertView.findViewById(R.id.textView1); 9        imageView.setImageResource(R.drawable.icon);10        textView.setText(title[position]);11        return convertView;12     }

3. ViewHolder的应用。View的findViewById()方法也是比较耗时的,因此需要考虑只调用一次,之后就用View.getTag()方法来获得ViewHolder对象。

1 public View getView(int position, View convertView, ViewGroup parent) { 2        // TODO Auto-generated method stub 3        ViewHolder holder; 4        if(convertView == null){ 5            convertView = (LinearLayout)this.layoutInflater.inflate(R.layout.list, null); 6            holder = new ViewHolder(); 7            holder.tv = (TextView)convertView.findViewById(R.id.textView1); 8            holder.im = (ImageView)convertView.findViewById(R.id.imageView1); 9            convertView.setTag(holder);10        }else{11            holder = (ViewHolder)convertView.getTag();12            Log.d("list", "convertView....");13        }14        holder.im.setImageResource(R.drawable.icon);15        holder.tv.setText(title[position]);16        return convertView;17     }18  19     static class ViewHolder{20        TextView tv;21        ImageView im;22     }

这种方法为View设置了Tag属性,通过setTag()方法将View的ImageView、TextView组件的对象添加到Tag 中,当回收利用时直接用getTag()方法取出,不需要重新获取组件。

 

ListView的优化三原则

1.复用convertView。

在getItemView中,判断convertView是否为空,如果不为空,可复用。

2.异步加载图片

item中如果包含有webimage,那么最好异步加载

3.快速滑动时不显示图片

当快速滑动列表时(SCROLL_STATE_FLING),item中的图片或获取需要消耗资源的view,可以不显示出来;而处于其他两种状态(SCROLL_STATE_IDLE 和SCROLL_STATE_TOUCH_SCROLL),则将那些view显示出来;在做ListView加载数据时如果数据量大的话会造成加载时间过长而卡屏,所以为了解决这个问题,查看了SDK,在OnScrollListener中有两个方法只要重写这两个方法就可以实现滚动加载,例如:

1 public void onScroll(AbsListView v, int firstVisibleItem,    int visibleItemCount, int totalItemCount) {   2  3    lastItem = firstVisibleItem + visibleItemCount - 1;    4  5   if (adapter.count == lastItem) {     6  7   adapter.count += 10;    adapter.notifyDataSetChanged();   8  9    }10 }11 public void onScrollStateChanged(AbsListView view, int scrollState) {   12 13 // TODO Auto-generated method stub14   Log.i("onScrollStateChanged", "onScrollStateChanged"); 15 16 }

 

转载于:https://www.cnblogs.com/onlive/archive/2013/04/03/2998658.html

你可能感兴趣的文章
Uint8Array 对象
查看>>
ResGen.exe”已退出,代码为2 问题处理
查看>>
TopFreeTheme精选免费模板【20130629】
查看>>
【转】C++ 类中的static,const,及引用类型的初始化
查看>>
find命令
查看>>
2019ICPC西安邀请赛 - B. Product - 数论
查看>>
Windows Store App JavaScript 开发:文件选取器
查看>>
ios修改产品名
查看>>
C++中string erase函数的使用
查看>>
PostgreSQL 对字段大小写敏感
查看>>
TCP和UDP的"保护消息边界”
查看>>
SQL游标使用实例
查看>>
Struts国际化
查看>>
信息安全系统设计基础第八周期中总结
查看>>
Java笔记(十七) 异步任务执行服务
查看>>
点击切换panel
查看>>
sqoop mysql导入hive 数值类型变成null的问题分析
查看>>
phpstorm中数组格式对齐
查看>>
url介绍
查看>>
Mongodb常用命令
查看>>