android app -- 关于listview的几种用法(复用,不复用,半复用)解决item状态改变的问题
来源:互联网 发布:淘宝网交电费 编辑:程序博客网 时间:2024/06/06 05:47
1.从最基本的不复用开始,也就是在Adapter 的getView方法中不使用ViewHolder。
这样做,也就是在listView上下滑动,被隐藏的项滑出来的时候,每次都重绘一次这一项,这样的话会耗内存,如果item的数据量比较大的话很有可能出现滑动卡顿的现象。明显的卡顿是开发者最不愿意看到的,所以这样的使用方式,基本被pass掉了。
2.让每一项进行复用,也就是增加ViewHolder 到Adapter的getView中去。具体看代码
package com.tdotapp.rd.adapters;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;import com.tdotapp.rd.R;import java.util.List;/** * Created by GT on 2015/11/16. */public class typeAdapter extends BaseAdapter { //上下文 private Context mContext; //item 中绑的数据 private List<String> listBeans; //构造方法 public typeAdapter(Context context, List<String> listBeans) { this.mContext = context; this.listBeans = listBeans; } @Override public int getCount() { return listBeans.size(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { //ViewHolder ViewHolder viewHolder=null; //绘制每一项的时候先判断convertView是否为空,不为空,则else里面去复用,为空,则重新赋予item布局 if (convertView == null) { //new出ViewHolder ,初始化布局文件 viewHolder = new ViewHolder(); convertView = LayoutInflater.from(mContext).inflate(R.layout.type_spinner_item, null); viewHolder.tvfabuwz = (TextView) convertView.findViewById(R.id.tvfabuwz); //调用convertView的setTag方法,将viewHolder放入进去,用于下次复用 convertView.setTag(viewHolder); } else { //复用已经存在的item的项 viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.tvfabuwz.setText(listBeans.get(position)); return convertView; } class ViewHolder { TextView tvfabuwz; }}代码上增加了详细的注释,复用绝对是listView最优的优化方案,不用每次都绘制新的item项,创建一次,之后就拿来复用界面,这样一来,再多的项也不用卡耗内存了。原理相当于在上滑和下滑的时候,界面还是原来的,只是把数据换了一下。
复用有复用的好处,当然也有坏处。使用复用的时候,如果每一项里面只是展示数据,复用绝对好使,但是如果listView中的每一项都能操作(比如有个editText,输入内容,上下滑动之后,看输入框里面的内容是不是要被改变,或者在下面复用的时候出现了这个输入框里面的内容。比如,一个单选框,这一项选中之后,上下滑动之后,看这个选中状态是不是乱跑了,之前的选中状态是不是消失了。。。。。等等等,凡是与item项状态有关的,复用的时候肯定就出问题了)
怎么解决呢,这个时候你想到的肯定是不复用吧,不复用就不会出现状态改变的情况了,但是你要想清楚,不复用的话,或许滑动一会,你的这个listView就会因为不停重绘item界面而内存消耗过大,出现滑不动的情况。
下面就来说下如何避免这样的情况出现,即保证滑动之后item项修改的状态还在,又保证不会过多的重绘item使内存消耗多大。
本方法出自 xiaanming大牛的博客(稍做改动)
public class NewsAdapter extends BaseAdapter { // 定义Context private Context mContext; List<NewsListBean> list = new ArrayList<>(); //定义hashMap 用来存放之前创建的每一项item HashMap<Integer, View> lmap = new HashMap<Integer, View>(); private ImageLoader imageLoader = ImageLoader.getInstance(); public NewsAdapter(Context context, List<NewsListBean> listViewList) { this.mContext = context; this.list = listViewList; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return position; } @Override public long getItemId(int position) { return 0; } @Override public View getView(final int position, View convertView, ViewGroup parent) { ViewHolder ViewHolder; //创建每一个滑动出来的item项,将创建出来的项,放入数组中,为下次复用使用 if (lmap.get(position) == null) { convertView = LayoutInflater.from(mContext).inflate(R.layout.news_item, null); ViewHolder = new ViewHolder(convertView); convertView.setTag(ViewHolder); lmap.put(position,convertView); } else { convertView = lmap.get(position); ViewHolder = (ViewHolder) convertView.getTag(); }ViewHolder.tv_newstime.setText(list.get(position).getDate()); ViewHolder.tvnewsneirong.setText(list.get(position).getContent()); ViewHolder.tvnewstitle.setText(list.get(position).getTitle()); imageLoader.displayImage(list.get(position).getImg(), ViewHolder.imgnewspic, Tools.setBeforImageoption()); return convertView;}//添加viewHolderclass ViewHolder { TextView tvnewstitle,newstype,tvnewsneirong,tv_newstime; ImageView imgnewspic; public ViewHolder(View convertView) { tvnewstitle = (TextView) convertView.findViewById(R.id.tvnewtitle); imgnewspic = (ImageView) convertView.findViewById(R.id.imgnewspic); newstype= (TextView) convertView.findViewById(R.id.newstype); tvnewsneirong= (TextView) convertView.findViewById(R.id.tvnewsneirong); tv_newstime= (TextView) convertView.findViewById(R.id.tv_newstime); }}
原理就是,有新的界面了,重绘,已经存在的界面直接拿出来。这样一来,每一次的新的item项会被重新绘制界面,并将重绘的界面放入集合中做保存,可以有效的防止item项状态因服用被改变的问题出现。
但是这样的话,复用将大打折扣。内存消耗也会有所提升。
看夏大的博客回复中,有大神提到可以将状态也同时放入tag中做保存,同样在实现复用的时候复用状态。
- android app -- 关于listview的几种用法(复用,不复用,半复用)解决item状态改变的问题
- android app -- 关于listview的几种用法(复用,不复用,半复用)解决item状态改变的问题
- android app -- 关于listview的几种用法(复用,不复用,半复用)解决item状态改变的问题
- ListView的复用问题,点击条目变色.不复用
- ListView等的样式和内容适配器不复用问题
- ListView等的样式和内容适配器不复用问题
- 解决“listView点击一个Item,另外几个Item也跟着改变”的问题
- 解决“listView点击一个Item,另外几个Item也跟着改变”的问题
- 关于Android中Listview的item点击不响应问题的解决
- android的listview,怎么改变item内容?
- 改变listview中item的子控件的状态
- android 鼠标悬停状态下改变背景色(类似Button、listview item 的selector)
- Android ListView item 点击事件失效问题的解决
- 【完美解决】Android ListView item 点击没有响应的问题
- Android 解决listview 的item高度,边距失效问题
- android listView列表item下子列表的几种方法
- 解决: 用代码改变listview的item背景色时,点击一个item,每隔几个item背景色重复
- Android BaseAdapter和ViewHolder 优化 解决ListView的item抢焦点问题和item错乱问题
- Android Button按钮点击时和松开的效果
- DataSet的排序的问题
- python实现的遗传算法实例(一)
- python wsgi 详解浏览器请求过程
- 快速Android开发系列通信篇之EventBus
- android app -- 关于listview的几种用法(复用,不复用,半复用)解决item状态改变的问题
- 新一代基于大数据的管理信息系统(MIS)报表需求开发
- flux 基础
- C# 操作Access的Ole对象
- Eclipse中jsp、js文件编辑时,卡死现象解决汇总
- [转载] 最全Android 编程下 Touch 事件的分发和消费机制
- Android组件(一)-Calendar、DataPickerDialog、PreferenceActivity、CoordinatorLayout
- cocoaPods导入第三方后不提示的解决方法
- ubuntu下导入导出.sql