ListView的优化问题以及策略

ListView这个布局经常用到,这个布局中有一个方法getView需要我们来实现,如果使用没有优化的ListView,还是比较消耗内存。下面说一下优化ListView的方法:

主要从两个方面:

首先没有之前的getView方法:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
	View view = View.inflate(SelectContactActivity.this, R.layout.list_item_contact, null);
	TextView tv_contact_name = (TextView) view.findViewById(R.id.tv_contact_name);
	tv_contact_name.setText(contactInfo.get(position).get("name"));
	TextView tv_contact_num = (TextView) view.findViewById(R.id.tv_contact_num);
	tv_contact_num.setText(contactInfo.get(position).get("phone"));
	return view;
}


1、使用contentView缓存对象。

listview工作原理:当最上面或者最下面的一个Item被覆盖之后,系统会自动将其缓存起来,其实就缓存给了contentView,那么当我们每一次调用getView方法时就可以使用这个缓存对象,而不用每次都创新新的View对象,可以起到很好的优化内存的作用。

代码如下:

if(convertView != null){
	view = convertView;
	//System.out.println("缓存");
}else {
	view = View.inflate(AppManagerActivity.this,R.layout.item_app_manager , null);
	holder = new ViewHolder();
	tv_app_name = (TextView) view.findViewById(R.id.tv_app_name);
	tv_app_rom = (TextView) view.findViewById(R.id.tv_app_rom);
	iv_app = (ImageView) view.findViewById(R.id.iv_app);
	bt_uninstall = (Button) view.findViewById(R.id.bt_uninstall);
	iv_app_lock = (ImageView) view.findViewById(R.id.iv_app_lock);
	//System.out.println("新建");
}
2、使用ViewHolder缓存对象。

先直接上代码,   先定义 ViewHolder对象,相当于一个口袋,用于记录空间的对象,用这种方法效率提升不是很大,大概提升5%。

/**
* view对象的容器
*记录孩子的内存地址。
*相当于一个记事本
 */
static class ViewHolder{
	TextView tv_app_name;
	TextView tv_app_rom;
	ImageView iv_app;
	Button bt_uninstall;
	ImageView iv_app_lock;
}


View view;
ViewHolder holder;
if(convertView != null){
	view = convertView;
	holder = (ViewHolder) view.getTag();
	//System.out.println("缓存");
}else {
	view = View.inflate(AppManagerActivity.this,R.layout.item_app_manager , null);
	holder = new ViewHolder();
	holder.tv_app_name = (TextView) view.findViewById(R.id.tv_app_name);
	holder.tv_app_rom = (TextView) view.findViewById(R.id.tv_app_rom);
	holder.iv_app = (ImageView) view.findViewById(R.id.iv_app);
	holder.bt_uninstall = (Button) view.findViewById(R.id.bt_uninstall);
	holder.iv_app_lock = (ImageView) view.findViewById(R.id.iv_app_lock);
	//iv_app_lock
	view.setTag(holder);
	//System.out.println("新建");
}

3、使用分页加载与分批加载

分页加载与分批相互对立,无非时间换空间,空间换时间的问题。

首先是分页加载,顾名思义,就是一页一页的加载,触发某个事件,便会加载一部分数据,但是缺点是加载了下一页,那么上一页的数据也就丢掉了,如果要返回上一页,还要继续请求数据库,造成了时间的消耗,但是优点却是节省了内存。

对于分批加载,相对于分页加载,其实就是没有丢掉上一页的数据,那么返回上一页,就会立刻响应,在内存足够的情况下,分批加载用户体验较好。

无论是分页还是分批加载,都是动态加载数据,都比一次性加载全部数据到listView要节省内存,对于优化ListView也是功不可没。


4、使用scrollListener,记住滑动的状态

scrollListener与分页加载或者分批加载一起使用,相当于scrollListener作为上述的触发事件,当滑动到每个状态的开始继续加载数据。

说什么都没有上代码来的直接

lv_black_num.setOnScrollListener(new OnScrollListener() {
	
	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		switch (scrollState) {
		case OnScrollListener.SCROLL_STATE_FLING://惯性滑动状态
			int lastPositon = lv_black_num.getLastVisiblePosition();
			if(lastPositon == blackNumList.size() - 1) {
				//继续加载数据
				System.out.println("继续加载数据");
				if(dataFlag) {
					offset += maxNumList;
					//System.out.println("继续加载数据");
					fillData();
				}else {
					//tv_loaddata.setText("没有更多数据了");
					//System.out.println("没有更多数据了");
					Toast.makeText(CommunicationSafeActivity.this, "没有更多数据了", 1).show();
				}
				
			}
				
			break;
		case OnScrollListener.SCROLL_STATE_IDLE://空闲状态
			
			break;
		case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL://手指滑动状态
			
			break;
		default:
			break;
		}
		
	}
	
	@Override
	public void onScroll(AbsListView view, int firstVisibleItem,
			int visibleItemCount, int totalItemCount) {
		// TODO Auto-generated method stub
		
	}
});







你可能感兴趣的:(ListView的优化问题以及策略)