解决ListViews适配器notifyDataSetChanged()无效问题

声明:1,要使mAdapter.notifyDataSetChanged()有效的前提条件是数据发生变化!!!

             2,new操作在java中是创建一个新的对象,实际上跟c语言一样,会在内存中开辟一个新的空间,这里就会牵扯到数据的址传递和值传递问题。


以下是一般使用场景,但问题就出现在这种场景之中:

//适配器的数据源
public List<String> mDatas;

/** 获取数据的方法 */
public void getData() {

	//一个临时变量,用于存放数据
	List<String> fileItemList = new ArrayList<String>();
	//生成随机数,控制循环次数
	int sum = new Random().nextInt(10);
	for(int i=0;i<sum;i++){
		fileItemList.add(i + " ");
	}
	
	//然后给数据源赋值
	mDatas = fileItemList;
}

/** 自定义的适配器 */
class MyAdapter extends BaseAdapter{

	@Override
	public int getCount() {
		if(mDatas!=null){
			return mDatas.size();
		}
		return 0;
	}

	@Override
	public Object getItem(int position) {
		if(mDatas!=null){
			return mDatas.get(position);
		}
		return null;
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		TextView tv = new TextView(getActivity());
		tv.setText(mDatas.get(position));
		return tv;
	}
}

/** 初始化时给listView设置适配器 */
public void init(){
	MyAdapter mAdapter = new MyAdapter();
	mListView.setAdapter(mAdapter);
}

/** 刷新UI */
public void refreshUI(){
	//更新数据
	getData();
	//告诉适配器数据已更新
	mAdapter.notifyDataSetChanged();
}

分析:

1.上面这几步看似正常,但是效果是没有的(可能listView有数据但是不会刷新了,也可能一开始listView就没有数据显示,这跟自己给listView设置适配器的时机有关)。


2.这就是数据源没有更新造成的,在第一次获取数据时调用了getData()方法,在这个方法里有一个new操作,创建了一个存储数据的临时变量(fileItemList),再对mDatas进行赋值时是属于地址赋值,因为mDatas不是new出来的,所以可以这样认为,mDatas就是fileItemList,适配器被第一次创建时,与mDatas关联,实际上是跟fileItemList关联,适配器要更新数据就必须先让fileItemList的数据发生变化才行。


3.而第二次获取数据时是在调用了refreshUI()方法里调用的getData()方法,此时这个方法跟之前的一样,也是进行了new操作,生成了另一个临时变量(fileItemList),再把fileItemList赋值给mDatas,同理这也是属于地址赋值,所以此时mDatas就是第二个fileItemList,可以看出mDatas这个变量并没有起到数据源的作用,反而类似C语言中的指针,每次都指着不同的临时变量,而适配器关联的数据源是第一个临时变量(也就是这个适配器的数据源),所以,不管调用几次getData()方法去获取新数据都与第一个临时变量无关,那么mAdapter.notifyDataSetChanged()方法自然也就无效了。


解决方法如下,只要修改getData()即可:

/** 获取数据的方法 */
public void getData() {

	if(mDatas == null){
		//创建数据源
		mDatas = new ArrayList<String>();
	}else{
		//清空数据源
		mDatas.clear();
	}
	 
	//生成随机数,控制循环次数
	int sum = new Random().nextInt(10);
	for(int i=0;i<sum;i++){
		mDatas.add(i + " ");
	}
}

分析:

这样修改后,不管调用多少次getData(),数据源只创建一次,适配器关联到的数据源也会随getData()的调用一起变化,再调用mAdapter.notifyDataSetChanged()时就会有效果了,问题到此解决。







  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值