请教一个RecyclerView数据错乱的问题

当我点击点赞的时候,赞的图标变成蓝色,然后该点赞数+1.但是加载更多会出现数据错乱.比如我现在点赞的是第一条,但是加载更多后会变到第三条去了.
下面是效果图和代码:
图片描述

CommentsController类:

public class CommentsController extends TabController implements BaseQuickAdapter.RequestLoadMoreListener {

    @BindView(R.id.rv_comments)
    RecyclerView mRecyclerView;
    @BindView(R.id.rl_comments_empty_view)
    RelativeLayout mEmptyView;
    @BindView(R.id.rl_comments_loading)
    RelativeLayout mLoading;

    private static final String TAG = "CommentsController";
    private Context mContext;
    private List<CommentsBean> mDatas;
    private CommentsAdapter mAdapter;
    private String mVid;
    private int mListSize;
    private int mSize = 1;

    public CommentsController(Context context) {
        super(context);
        this.mContext = context;
    }

    @Override
    protected View initContentView(Context context) {
        View view = View.inflate(context, R.layout.controller_comments, null);
        ButterKnife.bind(this, view);
        return view;
    }

    @Override
    public void initData() {
        getInitData();
    }

    public void getInitData() {
        mSize = 1;//切换视频列表再切换评论需重置
        mListSize = 0;
        mLoading.setVisibility(View.VISIBLE);
        mVid = (String) BaseApplication.getApplication().getMap().get("vid");
        mDatas = new ArrayList<>();
        mAdapter = new CommentsAdapter(R.layout.item_comments, mDatas, mContext);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mContext);
        linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(linearLayoutManager);
        mRecyclerView.setAdapter(mAdapter);
        getCommentsData();
    }

    /**
     * 获取初始化评论列表数据
     */
    private void getCommentsData() {
        ApiManager.getService()
                .commentsList(NetWorkRequestUtils.createRequestBody(new CommentsObject()))
                .compose(RxUtils.<BaseResponse<List<CommentsBean>>>schedulers((Activity) mContext))
                .subscribe(new HttpCallback<List<CommentsBean>>((Activity) mContext) {
                    @Override
                    public void onSuccess(List<CommentsBean> commentsBeans, String msg) {
                        mListSize += commentsBeans.size();
                        Log.d(TAG, "onSuccess: 1506= mListSize " + mListSize + ", commentsBeans=" + commentsBeans);
                        if (commentsBeans.size() >= 10)
                            mAdapter.setOnLoadMoreListener(CommentsController.this, mRecyclerView);//大于等于10条数据才去加载更多
                        if (mListSize == 0 && commentsBeans.isEmpty()) {
                            mEmptyView.setVisibility(View.VISIBLE);
                        } else if (commentsBeans != null && !ResponseUtils.isDataEnd(commentsBeans)) {
                            mSize++;
                            mDatas.addAll(commentsBeans);
                            mAdapter.notifyDataSetChanged();
                            mAdapter.loadMoreComplete();
                        } else {
                            mDatas.addAll(commentsBeans);
                            mAdapter.notifyDataSetChanged();
                            mAdapter.loadMoreEnd();
                        }
                    }

                    @Override
                    public void onComplete() {
                        super.onComplete();
                        mLoading.setVisibility(View.GONE);
                        if (mListSize > 0)
                            mEmptyView.setVisibility(View.GONE);
                    }
                });
    }

    @Override
    public void onLoadMoreRequested() {
        mRecyclerView.postDelayed(new Runnable() {
            @Override
            public void run() {
                getCommentsData();
            }
        }, 500);
    }

    private class CommentsObject {
        String vid = mVid;
        int p = mSize;
        int type = 1;
    }
}

CommentsAdapter类:

public class CommentsAdapter extends BaseQuickAdapter<CommentsBean, BaseViewHolder> {

    private Context mContext;
    private String mVid;
    private final String mToken;
    private boolean isLike;

    public CommentsAdapter(int layoutResId, @Nullable List<CommentsBean> data, Context context) {
        super(layoutResId, data);
        this.mContext = context;
        mVid = (String) BaseApplication.getApplication().getMap().get("vid");
        mToken = PreferenceUtils.getString(mContext, "token");
        Log.d(TAG, "CommentsAdapter: 1440= vid=" + mVid + ",    token=" + mToken);
    }

    @Override
    protected void convert(BaseViewHolder helper, CommentsBean item) {
        helper.setText(R.id.tv_comments_username, item.getNickname())
                .setText(R.id.tv_comments_date, item.getCtime())
                .setText(R.id.tv_comments_content, item.getContent());
        Glide.with(mContext).load(item.getHeadimg()).crossFade()
                .transform(new GlideRoundTransformUtils(mContext))//将图片转为圆形
                .into((ImageView) helper.getView(R.id.iv_comments_avatar));
        int position = helper.getLayoutPosition();
        LikeButton likeButton = helper.getView(R.id.comments_like_button);//点赞按钮
        TextView tvLikeCount = helper.getView(R.id.tv_video_comments_like_count);//点赞数
        likeComments(position, likeButton, tvLikeCount);//点赞评论

//        boolean like = item.isLike();
//        if(like){
//            likeButton.setLiked(true);
//        }else{
//            likeButton.setLiked(false);
//        }
    }

    private void likeComments(final int position, LikeButton likeButton, final TextView tvLikeCount) {
//        likeButton.setEnabled(true);//点赞开关,false为禁止点赞,默认true,用于无网络时禁止点赞
        boolean fastDoubleClick = FastClickUtils.isFastDoubleClick();//TODO:避免快速点击发起多次请求
//            likeButton.setLiked(true);//TODO:加载更多后数据错乱

        likeButton.setOnLikeListener(new OnLikeListener() {
            @Override
            public void liked(LikeButton likeButton) {
                //TODO:提交点赞结果到后台
                Toast.makeText(mContext, "点击了" + position, Toast.LENGTH_SHORT).show();
                int likeCount = Integer.parseInt(tvLikeCount.getText().toString().trim());
                int liked = likeCount + 1;
                tvLikeCount.setText(liked + "");
            }

            @Override
            public void unLiked(LikeButton likeButton) {
                //TODO:提交取消点赞结果到后台
                int likeCount = Integer.parseInt(tvLikeCount.getText().toString().trim());
                int liked = likeCount - 1;
                tvLikeCount.setText(liked + "");
            }
        });
    }
}
阅读 4.2k
1 个回答

这和listview的加载模式是一样的,设置了变动的一定记得给未设置的也设置数据,比如:你设置第一条未蓝色,那么其他要设置黑色,不要因为默认是黑色就不设置了。

listview和RecyclerView都是可见刷新的模式,比如这个文章的说法:
https://www.2cto.com/kf/20160...

官方在早期listview的时代有做过相关分享,可能是2014年的时候,不可考,大致清楚为什么,然后解决的方式就比较简单了,总得来说就是对所有的项目都要记录数据用以对展示进行判断。如果不记录就会出现错乱,因为是布局复用的方式。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题