Android使用notifyDataSetChanged刷新适配器数据无效

今天在写一个显示wifi信号强度的页面时候,发现在刷新数据的时候,无论如何都无法刷新。
在网上找了一些答案后才发现了问题所在。


    srlist = wifiAdmin.getAllNetWorkList();
    wifiadapter = new WifiSignalAdapter(srlist,app);
    wifiList.setAdapter(wifiadapter);

我在上面是通过一个wifiAdmin的工具类的getAllNetWorkLis()方法获取所有的wifi信息列表,
然后 我在线程中写的是
`

 while( !isStop){
                if(wifiAdmin.isOpenWifi()){
                    //创建一个更新UI的线程来更新ui
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            //打开wifi后  获取当前的wifi信号列表并且搭载数据
                            srlist = wifiAdmin.getAllNetWorkList();
                            wifiadapter.notifyDataSetChanged();

                        }
                    });
                }else{
                    //目前未打开wifi
                    wifiList.setAdapter(null);
                }

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

`
然后, 我发现无论线程怎么跑 就是无法刷新listview的数据。
百度了很久之后,发现一片博客上面写的是
对于一个listview,当我们把信息存放到一个List链表中时,然后又对这个链表进行流排序,最后去刷新适配器发现无改变,原因为咱们改变流链表中值得位置,但没有改变值在内存中所储存的地址,即引用没有改变,所以我们可以对adapter再new 一次,然后setAdapter 到相应的ListVeiw或者GridView即可解决问题。

看到这里 我才恍然大悟,明白了错的原因在于我每次都是使用 srlist = wifiAdmin.getAllNetWorkList(); 按照上面的说法就是 咱们改变流链表中值得位置,但没有改变值在内存中所储存的地址,即引用没有改变,也就是说,这个srlist被new过一次后 再次去new这个srlist的变量,适配器指向的还是以前的那个srlist地址而不是新new出来的srlist地址

那么,我们能不能不改变存储地址的情况下解决这个问题呢?
我接下来是这么改的

“`
while( !isStop){
if(wifiAdmin.isOpenWifi()){
//创建一个更新UI的线程来更新ui
runOnUiThread(new Runnable() {
@Override
public void run() {
//打开wifi后 获取当前的wifi信号列表并且搭载数据
List newlist = wifiAdmin.getAllNetWorkList();
srlist.clear();
srlist.addAll(newlist);

                            wifiadapter.notifyDataSetChanged();

                        }
                    });
                }else{
                    //目前未打开wifi
                    wifiList.setAdapter(null);
                }

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

现在,再运行一遍,发现有用了。
这种方法其实就是一种“曲线救国”的解法…..还有一种思路是
适配器里面写个刷新数据方法,然后在里面替换新数据后调notifydatachange
或者其他的,解决问题的方法很多,但是总的来说就像我同学说的那样
“黑猫白猫能抓老鼠就是好猫”

顺带感谢论坛里面的其他前辈大佬

参考博客 https://blog.csdn.net/yangyong915/article/details/41593069

猜你喜欢

转载自blog.csdn.net/qq_34877234/article/details/81409808