BaseAdapter的使用与优化
2016-03-13 10:49
344 查看
1.数据适配器:
2.BaseAdapter的基本方法:
3.ListView的显示和缓冲机制:
需要才显示,显示完就回收缓存,显示时先检查缓冲池有没有可用View,有的话直接调用,然后设置View内容,填充到相对应的位置。
ViewHolder优化BaseAdapter的思路:
BaseAdapter的优化过程:
(1)第一层次:没有任何处理,如果数据量少看将就,但是如果列表项数据量很大的时候,会每次都重新创建View,设置资源,严重影响性能,所以从一开始就不要用这种方式。
每次绘制View时候都用使用一次getView方法,都要重新获得布局和控件,完全没有使用到ListView的缓存机制。
(2)第二层次:通过缓存convertView,这种利用缓存contentView的方式可以判断如果缓存中不存在View才创建View,如果已经存在可以利用缓存中的View,提升了性能。
利用了ListView的换成机制,如果没有缓存才新建新的View,但是findViewById会浪费大量时间。
(3)第三层次:通过convertView+ViewHolder来实现,ViewHolder就是一个静态类,通过convertView .findViewById,viewHolder中已经绑定了各个控件,省去了findViewById的步骤。
当我们判断 convertView == null 的时候,如果为空,就会根据设计好的List的Item布局(XML),来为convertView赋值,并生成一个viewHolder来绑定converView里面的各个View控件(XML布局里面的那些控件),避免了findViewById的操作。再用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。
不仅利用了ListView的缓存,更通过ViewHolder类来实现显示数据的视图的缓存,避免多次通过findViewById寻找控件。
实例:
(1)activity_main.xml
(2)item.xml
(3)ItemBean.java
(4)MainActivity.java
(5)MyAdapter.java
参考资料:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1021/1815.html
http://www.imooc.com/learn/365
2.BaseAdapter的基本方法:
3.ListView的显示和缓冲机制:
需要才显示,显示完就回收缓存,显示时先检查缓冲池有没有可用View,有的话直接调用,然后设置View内容,填充到相对应的位置。
ViewHolder优化BaseAdapter的思路:
BaseAdapter的优化过程:
(1)第一层次:没有任何处理,如果数据量少看将就,但是如果列表项数据量很大的时候,会每次都重新创建View,设置资源,严重影响性能,所以从一开始就不要用这种方式。
public View getView(int position, View convertView, ViewGroup parent) { View view = mInflater.inflate(R.layout.item,null); ImageView imageView = (ImageView) view.findViewById(R.id.iv_image); TextView title = (TextView) view.findViewById(R.id.tv_title); TextView content = (TextView) view.findViewById(R.id.tv_content); ItemBean bean = mList.get(position); imageView.setImageResource(bean.ItemImageResid); title.setText(bean.ItemTitle); content.setText(bean.ItemContent); return view; }
每次绘制View时候都用使用一次getView方法,都要重新获得布局和控件,完全没有使用到ListView的缓存机制。
(2)第二层次:通过缓存convertView,这种利用缓存contentView的方式可以判断如果缓存中不存在View才创建View,如果已经存在可以利用缓存中的View,提升了性能。
public View getView(int position, View convertView, ViewGroup parent) { if(convertView == null) { convertView = mInflater.inflate(R.layout.list_item, null); } ImageView img = (ImageView)convertView.findViewById(R.id.img) TextView title = (TextView)convertView.findViewById(R.id.title); TextView info = (TextView)ConvertView.findViewById(R.id.info); img.setImageResource(R.drawable.ic_launcher); title.setText("Hello"); info.setText("world"); return convertView; }
利用了ListView的换成机制,如果没有缓存才新建新的View,但是findViewById会浪费大量时间。
(3)第三层次:通过convertView+ViewHolder来实现,ViewHolder就是一个静态类,通过convertView .findViewById,viewHolder中已经绑定了各个控件,省去了findViewById的步骤。
当我们判断 convertView == null 的时候,如果为空,就会根据设计好的List的Item布局(XML),来为convertView赋值,并生成一个viewHolder来绑定converView里面的各个View控件(XML布局里面的那些控件),避免了findViewById的操作。再用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。
//在外面先定义,ViewHolder静态类 //后面就可以通过设置成员变量设置布局控件内容,不再用findViewById了。 static class ViewHolder { public ImageView img; public TextView title; public TextView info; } //然后重写getView @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if(convertView == null) { holder = new ViewHolder(); convertView = mInflater.inflate(R.layout.list_item, null); //把convertView中的控件保存到viewHolder中 holder.img = (ImageView)convertView .findViewById(R.id.img) holder.title = (TextView)convertView .findViewById(R.id.title); holder.info = (TextView)convertView .findViewById(R.id.info); //通过setTag将ViewHolder与convertView绑定 convertView.setTag(holder); }else { //通过调用缓冲视图convertView,然后就可以调用到viewHolder,viewHolder中已经绑定了各个控件,省去了findViewById的步骤 holder = (ViewHolder)convertView.getTag(); } //就可以通过设置成员变量设置布局控件内容,不再用findViewById了。 holder.img.setImageResource(R.drawable.ic_launcher); holder.title.setText("Hello"); holder.info.setText("World"); } return convertView; }
不仅利用了ListView的缓存,更通过ViewHolder类来实现显示数据的视图的缓存,避免多次通过findViewById寻找控件。
实例:
(1)activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ListView android:id="@+id/lv_main" android:layout_width="match_parent" android:layout_height="wrap_content"/> </RelativeLayout>
(2)item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/iv_image" android:layout_width="60dp" android:layout_height="60dp" android:background="@drawable/ic_launcher"/> <LinearLayout android:orientation="vertical" android:layout_weight="1" android:layout_width="0dp" android:layout_height="60dp"> <TextView android:id="@+id/tv_title" android:layout_width="match_parent" android:layout_height="30dp" android:text="title" android:textSize="25sp" android:gravity="center"/> <TextView android:id="@+id/tv_content" android:layout_width="match_parent" android:layout_height="30dp" android:text="Content" android:textSize="20sp" android:gravity="center"/> </LinearLayout> </LinearLayout>
(3)ItemBean.java
package com.example.lenovo.baseadapter; //在要显示的数据和显示数据的布局文件中形成了,一一映射的关系 public class ItemBean { public int ItemImageResid; public String ItemTitle; public String ItemContent; public ItemBean(int itemImageResid, String itemTitle, String itemContent){ ItemImageResid = itemImageResid; ItemTitle = itemTitle; ItemContent = itemContent; } }
(4)MainActivity.java
package com.example.lenovo.baseadapter; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.ListView; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); List<ItemBean> itemBeanList = new ArrayList<>(); for (int i=0;i<20;i++){ itemBeanList.add(new ItemBean( R.drawable.ic_launcher, "我是标题"+i, "我是标题"+i )); } ListView listView = (ListView) findViewById(R.id.lv_main); listView.setAdapter(new MyAdapter(this,itemBeanList)); } }
(5)MyAdapter.java
package com.example.lenovo.baseadapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import java.util.List; public class MyAdapter extends BaseAdapter { //用LayoutInflater方法xml文件转换为View布局 private LayoutInflater mInflater; //(1)创建一个成员变量,存储传递进来的数据,这样在适配器中只要对成员变量操作就可以了 private List<ItemBean> mList; //(2)为了从数据源获取要使用的数据,通常在构造方法中对数据进行初始化 //通过(1)(2)把数据源和适配器关联起来了****** public MyAdapter(Context context,List<ItemBean> list){ mList = list; //context要使用当前的Adapter的界面对象 //mInflater布局装载器对象 //构造方法中对LayoutInflater对象初始化 mInflater = LayoutInflater.from(context); } @Override public int getCount() { return mList.size(); } @Override public Object getItem(int position) { return mList.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder; if (convertView==null){ viewHolder = new ViewHolder(); convertView = mInflater.inflate(R.layout.item,null); //把convertView中的控件保存到viewHolder中 viewHolder.imageView = convertView.findViewById(R.id.iv_image); viewHolder.title = convertView.findViewById(R.id.tv_title); viewHolder.content = convertView.findViewById(R.id.tv_content); //通过setTag将ViewHolder与convertView绑定 convertView.setTag(viewHolder); }else{ //通过调用缓冲视图convertView,然后就可以调用到viewHolder,viewHolder中已经绑定了各个控件,省去了findViewById的步骤 viewHolder = (ViewHolder) convertView.getTag(); } ItemBean bean = mList.get(position); viewHolder.imageView.setImageResource(bean.ItemImageResid); viewHolder.title.setText(bean.ItemTitle); viewHolder.content.setText(bean.ItemContent); return convertView; } class ViewHolder{ public ImageView imageView; public TextView title; public TextView content; } }
参考资料:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1021/1815.html
http://www.imooc.com/learn/365
相关文章推荐
- 计数排序、桶排序和基数排序
- 试用EVGA公版GTX980
- 堆优化SPFA
- c++11的使用心得(二)---右值引用
- Bootstrap 栅格系统
- 在RHEL7或者OL7上,Documents Fail to Index with DRG-11207: user filter command exited with status 127
- 不停止MySQL服务增加从库的两种方式【转载】
- 在CentOS上安装Java环境详解
- JavaSE知识集锦(1)深拷贝与浅拷贝
- 设计模式之Iterator
- 受限玻尔兹曼机RBM实现——matlab实现
- c# lock (obj) 与 lock (this) 区别
- python 多线程学习
- 虚函数里面调用虚函数的输出
- 短信防火墙
- 朴素贝叶斯法
- 第三周项目一 个人所得税计算器
- c语言中逗号运算符和逗号表达式
- 链式队列
- 第三周项目3:输出星号图