notifyDataSetChanged() 方法不更新数据的问题

一般我们习惯于使用 notifyDataSetChanged() 方法去更新 ListView 的数据,但是当有一天你发现调用这个方法没有更新数据的时候。。。我的心情是非常沮丧的。因为就在这段代码旁边的另外一个方法中也调用了 notifyDataSetChanged(),并且是有效的!这样我就更加郁闷了。

当然不能一直郁闷+沮丧啊,还是得找原因啊。这里我把正确的调用了更新的方法叫做 A ,无效的调用更新的方法叫做 B。

一开始以为是 Adapter 实例的引用问题,就把 adapter 的实例化从方法 A 里拿出来放到了 Activity 的 onCreate() 方法中(之前方法 A 也是在 onCreate() 中一开始就调用的),但是并没有什么卵用。然后查看 log 也没有发现相关的异常,那么肯定不是引用异常了,此项排除。

然后通过对比我发现 A 调用所关心的是 List 的所有变化,也就是只要 List 的内容发生任何变化都会更新数据。由此又能知道数据源的变化也没有问题。

这可真是怪了,之能从错误的调用重头开始查看。由于 B 关心的变化是 List 数量的变化,那么就去看 adapter 的 getCount() :

1
2
3
public int getCount() {
return isShowSysTask ? taskList.size() + 2 : userTaskList.size() + 1;
}

根据 isShowSysTask 的布尔值来分别设置不同的数量嘛,就是这么回事。所以乍一看没发现什么问题。

再看方法 B :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void showSysTask(boolean isShowSysTask) {
if (mMenu == null) {
return;
}
mMenu.getItem(2).setVisible(!isShowSysTask);
//mMenu.getItem(2).setEnabled(!isShowSysTask);
mMenu.getItem(3).setVisible(isShowSysTask);
//mMenu.getItem(3).setEnabled(isShowSysTask);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("show_sys_task", isShowSysTask);
editor.apply();
//不要忘记更新数据哟
myAdapter.notifyDataSetChanged();
//System.out.println("数据已经更新了");
}

嗯,根据 isShowSysTask 的布尔值来动态显示或隐藏某个菜单项,并且把这个布尔值存到 xml 里,好像也没什么错啊,就是这个方法的 参数名看着眼熟……

貌似跟上面的 getCount() 里的判断的布尔值名字一样啊!

隐约觉得有什么不对的地方。再仔细的看了下 getCount() 里的 isShowSysTask 值的变化:

1
isShowSysTask = preferences.getBoolean("show_sys_task", false);

也有赋值啊,真是奇怪。又扫了一眼方法 B ,仔细想了想,终于发现了问题所在:

在方法 B 中,我是根据 方法的参数来设置菜单的隐藏显示,而且存到 xml 里的是方法参数的值,但是这里并没有改变 getCount() 方法里需要的参数的值啊。。。汗

而 A 之所以没有受到影响是因为 A 关心的预期变化中并不包括 isShowSysTask 的变化,也就是当第一次数据填充完毕后,isShowSysTask 的变化就跟 A 没有什么关系了。。

居然是因为参数名字一样忘记给关键的变量赋值了,真是的。。。赶紧加了一句改变了外面的 isShowSysTask 的值,出于保险,顺便把方法 B 的参数名也改了。

真是血淋淋的教训,如此低级的错误。。。简直不能饶恕自己!面壁思过去

再次跑了一遍,果然,没有问题了。

回想了下,发现我实在太依赖于 IDE 的自动提示了,以往变量忘记赋值,没有进行合适的声明,代码执行不到, IDE 都会提示,这一次因为 变量有声明、有赋值、有使用,所以 IDE 也没有提示,导致了这个小小的错误,但是这也不能怪 IDE ,毕竟 Android Studio 已经是非常棒的开发环境了,完爆 Eclipse 好几条街啊。不过也许就是因为 IDE 的智能,让我忘记了自主思考,而忽略了这么重要的一点常识。以后还是得经常性地回过头来稍微思考一下,温故而知新,才能不断进步啊。

正如我的博客副标题:最可怕的是不会思考。