RecyclerView.Adapter notifyDataSetChanged 不起作用

来源:互联网 发布:21天学通java第7版好吗 编辑:程序博客网 时间:2024/05/22 06:54

转载地址 :http://blog.csdn.net/u011240877/article/details/51200715

最近项目里要添加个聊天功能,我们使用的是环信SDK。

如果应用启动,不在聊天界面,接收到消息后就弹出通知栏消息通知用户,点击进入聊天界面。

如果用户已经在聊天界面,就要将接收到的数据添加到adapter里,动态显示消息。

问题卡在,接收到消息后调用更新界面回调,给adapter里add新数据,然后调用adapter.notifyDataSetChanged()。

结果数据并没有刷新!

查看log,调用notifyDataSetChanged()后,onCreateViewHolder、onBindViewHolder方法并没有执行。

找了很久,最后在StackOverFlow上找到了答案,原文在这里

原来在我后台接收到数据调用更新界面回调方法时,其实和当前Activity不在同一个线程,我忙傻了把这点给忘了。

在回调里应该通过Handler发送数据到主线程,然后再给adapter里填数据,调用notifyDataSetChanged();

线程回调方法里:

 Message handleMsg = new Message();        Bundle bundle = new Bundle();        bundle.putParcelable("1",message);        handleMsg.setData(bundle);        handleMsg.what = 1;        updateChatHandler.sendMessage(handleMsg);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

处理消息的Handler:

Handler updateChatHandler = new Handler(){        @Override        public void handleMessage(Message msg) {            switch (msg.what){                case 1:                    EMMessage message = msg.getData().getParcelable("1");//                    UIUtils.showToastSafe(WaitForChatActivity.this, "接收到消息的回调" + message.getBody());                    setChatDataFromNet(message);                    if (adapter != null) {                        addData2Adapter(receiveMsg, false);                    }                    break;            }            super.handleMessage(msg);        }    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

总结

更新数据时在主线程填数据,然后再调用RecyclerView.Adapter的 notifyDataSetChanged方法。

Android 开发过程中经常遇到更新界面没反应的情况,一开始我总是觉得自己代码这么完美!一定是数据或者编译器问题,结果一次次被打脸。T。T

今天总结下开发过程中遇到的几种更新 UI 没反应原因:

  1. 数据为空

有时候服务端返回数据有误或者自己传递的数据为空,可以打个 Log 或者 跟个断点看看。

  1. 在子线程更新 UI

有时候在 请求接口回调、ListView 或者 RecyclerView 的 Adapter 里需要进行一些 UI 更新,这时不起作用的原因大多是因为我们在 子线程中更新UI。

子线程更新 UI 的方法有好多种,最终目的都是把消息发到主线程去操作:

写个 Handler 里进行 UI 操作,子线程 发送消息 
在runOnUiThread中

Activity.runOnUiThread(new Runnable() {        @Override        public void run() {            //do the ui-job        }    });

或者 post 到主线程

myView.post(new Runnable() {            @Override            public void run() {                //do the ui-job            }        })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.方法调用错误

最常见的就是修改 ImageVIew 图片,应该调用

setImageResource 
或者其他 setImageXXX 方法

而不是

setBackground 
等 setBackgroundXXX 方法,后者只是修改背景,而不是图片本身。


0 0
原创粉丝点击