Recyclerview刷新延迟的问题(刷新两次才更新数据)

  最近闲来开发一个自己游戏公会的小应用,成员介绍模块的实现用到了Recyclerview,从后台获取成员的详细信息然后Recyclerview展示。实现下拉刷新数据时,遇到了一个问题:后台数据更新后,下拉一次数据没有变化,再刷一次才显示到最新数据。最初的代码如下:

public  Handler memberRequestHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case Constant.HANDLER_REQUEST_MEMBERS:
                    mList = (List<MemberInfo>) msg.obj;                  
                    break;
            }
        }
    };


    @Override
    public void onCreate(Bundle savedInstanceState) {      
        super.onCreate(savedInstanceState);
    }

 @Override
    public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
        if (null == contentView) {

            contentView = inflater.inflate(R.layout.fragment_member, container, false);
            refreshLayout = (SwipeRefreshLayout) contentView.findViewById(R.id.refreshLayout);
            recyclerView = (RecyclerView) contentView.findViewById(R.id.recyclerView);
            recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
            initRefreshView();
            if(adapter == null){
                adapter = new MemberAdapter(mContext);
                recyclerView.setAdapter(adapter);
            }

            onRefreshListener = new SwipeRefreshLayout.OnRefreshListener() {
                @Override
                public void onRefresh() {
                        mThread = new GetMemberItemThread(memberRequestHandler);
                        mThread.start();
                        adapter.setData(mList);
                        adapter.notifyDataSetChanged();
                        refreshLayout.setRefreshing(false);
                }
            };
            refreshLayout.setOnRefreshListener(onRefreshListener);
            refreshLayout.post(new Runnable() {
                @Override
                public void run() {
                    refreshLayout.setRefreshing(true);
                    onRefreshListener.onRefresh();
                }
            });

        } else {
           ((ViewGroup) contentView.getParent()).removeView(contentView);
        }
        return contentView;
    }

其中,GetMemberItemThread类是获取后台成员信息的线程,在其run方法中handler将结果通过msg传递到主线程。上面的代码是在handleMessage中得到mList,然后在onrefresh中为adapter设置数据,最后调用adapter.notifyDatasetChanged()更新数据,这样就出现前面所述的问题。上面代码看起来没什么问题,GetMemberItemThread线程start后执行run方法获取到memberInfo,然后hanlder获取到赋值给mList,最后在onfresh中设置给adapter。想了半天也没有想到哪里出问题,后来调试发现GetMethodItemThread启动后并没有像想象中那样立即运行run方法,而是进入到onCreateView中,并且mList的大小为0!网上查了资料得知线程start后只是表示线程处于就绪状态,它首先做了创建线程等一系列工作,然后调用行的run()方法,run()方法只是一个类中的普通方法,直接执行和普通的方法没有什么两样。这样mList的size为0的原因就好解释了,onRefresh方法调用后,handler的msg从send到handle中间有一个时间,这是不可人为操控的,受很多因素影响。数据刷新延迟的原因就是mList还没赋值前就已经调用了setAdater。解决这一问题的方法就是将mList的赋值和设置adapter一起放在handleMessage中,这样就保证了mList的数据取得之后才设置adapter。更改后的代码如下:
  

public  Handler memberRequestHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case Constant.HANDLER_REQUEST_MEMBERS:
                    mList = (List<MemberInfo>) msg.obj; 
                    //将下面onRefresh()中的adapter设置数据添加到此处
                    adapter.setData(mList);
                    adapter.notifyDatasetChanged();
                    refreshLayout.setRefreshing(false);                
                    break;
            }
        }
    };

...

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

 @Override
    public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
        if (null == contentView) {

            contentView = inflater.inflate(R.layout.fragment_member, container, false);
            refreshLayout = (SwipeRefreshLayout) contentView.findViewById(R.id.refreshLayout);
            recyclerView = (RecyclerView) contentView.findViewById(R.id.recyclerView);
            recyclerView.setLayoutManager(new LinearLayoutManager(mContext));
            initRefreshView();
            if(adapter == null){
                adapter = new MemberAdapter(mContext);
                recyclerView.setAdapter(adapter);
            }

            onRefreshListener = new SwipeRefreshLayout.OnRefreshListener() {
                @Override
                public void onRefresh() {
                    mThread = new GetMemberItemThread(memberRequestHandler);
                    mThread.start();
                   //此处的adapter设置数据去掉,并把refreshLayout.setRefresh(false)
                   //移动到上面,这样保证加载数据完成后,加载动画才结束。                          
                }
            };
            refreshLayout.setOnRefreshListener(onRefreshListener);
            refreshLayout.post(new Runnable() {
                @Override
                public void run() {
                    refreshLayout.setRefreshing(true);
                    onRefreshListener.onRefresh();
                }
            });

        } else {
           ((ViewGroup) contentView.getParent()).removeView(contentView);
        }
        return contentView;
    }

  希望对大家有所帮助,如果有什么理解不对的地方,欢迎指正。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值