Andorid ListView和Adapter优化
来源:互联网 发布:软件改变生活 编辑:程序博客网 时间:2024/05/17 11:04
今天来说一下Android 中ListView控件 和使用Adapter 绑定数据。
现在分别列出两个对象的说明:
ListView
- 通常我们如果加载比较多相同类型的数据,会使用ListView,使用ListView有说明好处呢。ListView是一个可以滚动的视图控件,加载一条一条的Item数据是很好的选择。为什么说它好。原因就是ListView 只有在可见的范围内才加载数据,一但数据被划出屏幕之外,数据就会进入缓存或者销毁,可以节省很多内存。如果传统做法的话,就需要一次性把所有数据加载到内存,系统负荷比较重。
Adapter
- Adapter又是怎么东西呢?
在我们需要使用ListView这样展示相同结构 Item 的时候,就需要用到Adapter来进行数据匹配,说通俗点就是:把数据绑定到一个列表类的视图中去。
下面我先个简单Adapter
SimpleAdapter adapter; adapter=newSimpleAdapter(context,data,resource,from,to);`
这个Adapter传进来5个参数,下面分别对这些参数进行讲解:
- context ——上下文对象(这个在这里我不详细讲解,网上很多资料)
- data——这个参数要求的是一个
List<Map<String,Object>>
集合,里面装的数据是Map<String,Object>
集合,通常我们需要把数据装到Map集合里面,再把Map集合装到List集合里面去即可。 - resource ——指的是自定义的布局文件,里面需要设好对应控件的id
- form ——是一个String数组,里面放的是你定义Map集合时用到的key值,数据顺序和后面一个参数要一一匹配
- to ——resource参数对对应的布局文件中的控件 id ,和前一个参数一一对应。
可能有人还不不明白上面所说,下面给一个例子。
List<Map<String,Object>> data=new ArrayList<Map<String,Object>>(); Map<String,Object> map = new HashMap<String, Object>(); map.put("name", "haha"); data.add(map); SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.test, new String[]{"name"},new int[]{R.id.name});
上面一段代码的意思是将你放进map里面的key为name的值放到R.layout.test 布局中的 id 为 name 的控件中,如果有多条数据,就用for循环创建多个Map集合,把它添加到List集合即可,ListView会用布局文件作为一个Item的布局显示出来一个列表。
其实在开发中,用的最多的还是自定义Adapter ,自定义Adapter需要自定义一个类继承BaseAdapter,BaseAdapter有几个方法需要你实现:
假设我要放在listview数据已经存在一个List集合里面,名为list
- public int getCount() ——返回你需要显示的数据条目的数量(list.size())
- public Object getItem(int position )——返回要显示的数据中的第position个数据(list.get(position))
- public long getItemId(int position)——-返回条目ID (position)
- public View getView(int position, View convertView, ViewGroup parent) 该方法在需要显示数据的时候调用,即在滑动ListView的时候调用,传进来几个参数需要说明一下,position指的数第几个条目,converView指的是缓存view对象(一般条目被划出屏幕都会被缓存),ViewGroup指,父节点,一般不用理会。
说完几个需要实现的方法了,那么我们应该怎么做呢,其实很简单,getView方法就是要我们返回每一个Item执行的方法,在listview 每在屏幕中出现一个新的Item都会调用一次该方法。而且每一次都会把Item是第几个通过position参数传进来。我们在里面就可以通过 View v = View.inflate(MainActivity.this, R.layout.item, null);
方法来加载布局文件,同时通过该View对象找到里面的子控件。最后我们把这个View对象返回就是需要显示的Item了。
说那么多没什么用,用一个实例说明吧。
加入我有布局文件item.xml
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/salary" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/phone" android:layout_width="wrap_content" android:layout_height="wrap_content" /></LinearLayout>
我需要以该布局作为一个item的布局,然后把数据显示出去。
class MyAdapter extends BaseAdapter{ private List<Person> list = new ArrayList<Persom>(); public void MyAdapter(){ for(int i =0 ;i< 10;i++){//初始化数据,姓名,薪水,电话号码 list.add(new Person("哈哈"+1,10000+i,"1387894"+i)) } } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) {View v = View.inflate(MainActivity.this, R.layout.item, null); TextView name = (TextView) v.findViewById(R.id.name); TextView salary = (TextView) v.findViewById(R.id.salary); TextView phone = (TextView) v.findViewById(R.id.phone); Person p = list.get(position); name.setText(p.getName()); salary.setText(p.getSalary()); phone.setText(p.getPhone()); return v; } }}
这样简单的代码就能把数据绑定到ListView了。
其实这样的代码有2点不好的地方:
- gerView 方法存进来的是一个convertView对象,该对象是缓存视图,在listview第一次加载的时候,该对象为空,但是一旦listview滑动,就会有对象保存到convertView中去了,所以我们不必要每次调用getView都需要创建加载一个布局文件,我们可以先判断convertView是否为空,不为空的话,可以直接使用。
- 每次调用都会执行几次findViewById方法,这样也会耗费不必要的资源,我们可以定义一个ViewHolder,每次找到了子空间就存放在ViewHolder中,然后通过
setTag
方法把ViewHolder绑定到view对象中,当缓存中获取该view对象中,里面就包含了对应的ViewHolder对象,节省了不必要的操作。
最终代码如下:
class MyAdapter extends BaseAdapter{ private List<Person> list = new ArrayList<Persom>(); public void MyAdapter(){ for(int i =0 ;i< 10;i++){//初始化数据,姓名,薪水,电话号码 list.add(new Person("哈哈"+1,10000+i,"1387894"+i)) } } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { //从布局文件填充称为view对象 /** * 第二个参数convertView 是缓存视图 * 优化过程是,getView会传进来一个convertView对象,该对象是缓存的视图, * 为了使程序优化,避免出现OOM,所以我们需要判断converView是否为空, * 不为空就返回convertView ,问题来了:当listview滑动几次之后,convertView * 就不一定是我们所需要的那个View对象,所以最后要把view对象的数据重新绑定,这样就 * 不会出问题了。 */ View v = null; //当缓存不为空的时候,就填充视图,该代码优化了内存的使用 ViewHolder mHolder = null; if(convertView == null){ v = View.inflate(MainActivity.this, R.layout.item, null); mHolder = new ViewHolder(); mHolder.name = (TextView) v.findViewById(R.id.name); mHolder.salary = (TextView) v.findViewById(R.id.salary); mHolder.phone = (TextView) v.findViewById(R.id.phone); v.setTag(mHolder); //将mholder绑定到view对象中,通过getTag方法就可以回去对应的view 避免每次重复查找 }else{ //当缓存不为空的时候,就不必要执行findViewById操作了 v = convertView; mHolder = (ViewHolder) v.getTag(); } //因为convertView对象是指缓存中的内容,不一定是我们需要的那个view对象,所以要重新设值 System.out.println("getView调用:"+position); Person p = list.get(position); mHolder.name.setText(p.getName()); mHolder.salary.setText(p.getSalary()); mHolder.phone.setText(p.getPhone()); return v; } } /** * ViewHolder 的作用是为了避免每次调用getView的时候都要再执行findviewById()这样会耗费资源 * @author Jam * */ class ViewHolder{ TextView name; TextView salary; TextView phone; }}
以上就是我对ListView的一些总结了。
- Andorid ListView和Adapter优化
- registerDataSetObserver:浅析Andorid ListView和Adapter
- ListView优化-ListView 和 Adapter 原理
- Andorid之ListView优化
- ListView及其优化和Adapter的用法
- Listview Adapter 优化总结
- ListView的Adapter优化
- listView的 Adapter优化
- ListView 适配器(Adapter)优化
- ListView的adapter性能优化
- ListView GridView - Adapter的优化
- listview之adapter的优化
- listview超级优化的adapter
- Listview和 Adapter
- Adapter,BaseAdapter和ListView
- 关于ListView和Adapter
- listView和adapter用法
- ListView 和 Adapter
- 奋斗假分页
- JS登陆与注册验证
- C++对象模型——解构语意学(第五章)
- kafka0.8.2以下版本删除topic
- 深度学习文献阅读笔记(2)
- Andorid ListView和Adapter优化
- melody
- [持续更新]JavaScript学习笔记(四)
- Objective-C 苹果开发文档 04 Encapsulating Data
- 容斥定理 hdu1796 How many integers can you find
- list4
- 培训1
- jsp的基本知识
- 名字的漂亮度