今天学习了BaseAdapter的三种方法:
ListView的缓存机制:LIstView加载时不会把所有的数据都加载出来,而会把收集屏幕能放下的数据加载出来,当用户向下滑动使某些数据滑出屏幕时,这些数据会进入Recycler(view缓冲池)中,而新要显示的数据,会从缓冲池取出布局文件,重新设置好要显示的数据,再设置到屏幕。
结论:需要才会被显示,显示完就被回收到缓存,可以极大节省系统资源。
逗逼式(没有运用缓存机制,每次都创建新的View,不推荐):
步骤:
1.在主界面建立LIstView
2.建立容器类设置属性
public classItemBean {
public intItemImageResouceID;
publicStringItemTitle;
publicStringItemContent;
publicItemBean(intitemImageResouceID,String itemTitle,String itemContent) {
ItemContent= itemContent;
ItemImageResouceID= itemImageResouceID;
ItemTitle= itemTitle;
}
}
3.建立数据布局文件
本次使用RelativeLayout布局,学会了android:layout_toEndOf和android:layout_below使用方法
public classMyAdapterextendsBaseAdapter {
privateListmList;
privateLayoutInflatermInflater;
//通过构造器使数据源与数据适配器关联,对数据进行初始化
publicMyAdapter(Context context,List list){
mList=list;
//context要使用当前Adapter的界面对象mInflater布局装载对象
mInflater=LayoutInflater.from(context);
}
@Override
//返回ListView需要显示的数据数量
public intgetCount() {
returnmList.size();
}
@Override
publicObjectgetItem(intposition) {
returnmList.get(position);
}
@Override
public longgetItemId(intposition) {
//返回索引对应的数据项
returnposition;
}
@Override
//返回每一项的显示内容
publicViewgetView(intposition,View convertView,ViewGroup parent) {
//使用LayoutInflater把布局文件转化为view
View view=mInflater.inflate(R.layout.item,null);
//注意用的是view
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.ItemImageResouceID);
title.setText(bean.ItemTitle);
content.setText(bean.ItemContent);
returnview;
}
}
4.在主活动中定义适配器
List itemBeanList=newArrayList<>();
for(inti =0;i <20;i++) {
itemBeanList.add(newItemBean(
R.mipmap.ic_launcher,
"标题",
"内容"
));
}
ListView listView=(ListView)findViewById(R.id.lv_main);
listView.setAdapter(newMyAdapter(this,itemBeanList));
普通式
判断convertView是否被缓存过
修改代码为
publicViewgetView(intposition,View convertView,ViewGroup parent) {
if(convertView==null){
convertView=mInflater.inflate(R.layout.item,null);
}
ImageView imageView=(ImageView)convertView.findViewById(R.id.iv_image);
TextView title=(TextView)convertView.findViewById(R.id.tv_title);
TextView content=(TextView)convertView.findViewById(R.id.tv_content);
ItemBean bean=mList.get(position);
imageView.setImageResource(bean.ItemImageResouceID);
title.setText(bean.ItemTitle);
content.setText(bean.ItemContent);
returnconvertView;
}
利用了ListView的缓存特性,如果没有缓存才创建新的View
算是入门用法,但是findViewByID依然会浪费大量时间
文艺式
你的代码可能在 ListView 滑动时经常使用findViewById(),这样会降低性能。即使是 Adapter 返回一个用于回收的 inflate 后的视图,你仍然需要查看这个元素并更新它。避免频繁调用findViewById()的方法之一,就是使用 ViewHolder(视图占位符)的设计模式。
在文艺式中要避免两个耗时操作:
1.convertView的转换:避免重复创建大量convertView
2.对findViewByID进一步优化:使用ViewHolder
不仅利用了ListView的缓存,更通过ViewHolder类来实现显示数据的视图的缓存
避免多次通过findViewByID寻找控件
步骤:
1.创建ViewHolder内部类
2.判断convertView是否为空
3.通过setTag将ViewHolder和convertView绑定
4.若不为空通过getTag()取出关联的convertView
5.通过ViewHolder对象找到相应控件
ViewHolder viewHolder;
if(convertView==null){
viewHolder=newViewHolder();
convertView=mInflater.inflate(R.layout.item,null);
viewHolder.imageView=(ImageView)convertView.findViewById(R.id.iv_image);
viewHolder.title=(TextView)convertView.findViewById(R.id.tv_title);
viewHolder.content=(TextView)convertView.findViewById(R.id.tv_content);
convertView.setTag(viewHolder);
}else{
//不为空就可以取出
viewHolder=(ViewHolder)convertView.getTag();
}
ItemBean bean=mList.get(position);
viewHolder.imageView.setImageResource(bean.ItemImageResouceID);
viewHolder.title.setText(bean.ItemTitle);
viewHolder.content.setText(bean.ItemContent);
returnconvertView;
ViewHolder优化BaseAdapter思路
1.创建Bean对象,用于封装数据
2.在适配器构造方法中初始化用于映射的数据List
3.创建ViewHolder类,创建布局映射关系
4.判断convertView为空则创建,并设置Tag,否则通过tag来取出ViewHolder
5.给ViewHolder中的控件设置数据