Android解决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()时就会有效果了,问题到此解决。

 

 

 

 

 

 

人已赞赏
Android文章

Android开发调用系统的文件浏览器及文件浏览器的方法

2020-2-19 14:44:15

Android文章

Android开发实现3D翻转动画效果

2020-2-19 16:18:59

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索