RecyclerView在聊天屏幕中的notifyDataSetChanged上滚动到顶部

use*_*005 14 android notifydatasetchanged recycler-adapter android-recyclerview linearlayoutmanager

我正在尝试使用recyclelerView创建消息类型的屏幕,它将从底部开始,并在用户到达聊天的最高端时加载更多数据.但我正面临着这个奇怪的问题.

我的recyclerView在调用notifyDataSetChanged时滚动到顶部.由于这个onLoadMore被多次调用.

这是我的代码:

LinearLayoutManager llm = new LinearLayoutManager(context);
llm.setOrientation(LinearLayoutManager.VERTICAL);
llm.setStackFromEnd(true);
recyclerView.setLayoutManager(llm);
Run Code Online (Sandbox Code Playgroud)

**在适配器中

 @Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    if (messages.size() > 8 && position == 0 && null != mLoadMoreCallbacks) {
        mLoadMoreCallbacks.onLoadMore();
    }
Run Code Online (Sandbox Code Playgroud)

**在活动中

@Override
public void onLoadMore() {
    // Get data from database and add into arrayList
      chatMessagesAdapter.notifyDataSetChanged();
}
Run Code Online (Sandbox Code Playgroud)

这只是recyclerView滚动到顶部.如果滚动到顶部停止,则此问题将得到解决.请帮我弄清楚这个问题的原因.提前致谢.

Bor*_*rja 5

我认为您不应该那样使用 onBindViewHolder,删除该代码,适配器应该只绑定模型数据,而不是监听滚动。

我通常以这种方式执行“onLoadMore”:

在活动中:

private boolean isLoading, totallyLoaded; //
RecyclerView mMessages;
LinearLayoutManager manager;
ArrayList<Message> messagesArray;
MessagesAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //...
    mMessages.setHasFixedSize(true);
    manager = new LinearLayoutManager(this);
    manager.setStackFromEnd(true);
    mMessages.setLayoutManager(manager);
    mMessages.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);

            if (manager.findFirstVisibleItemPosition() == 0 && !isLoading && !totallyLoaded) {
                onLoadMore();
                isLoading = true;
            }
        }
    });
    messagesArray = new ArrayList<>();
    adapter = new MessagesAdapter(messagesArray, this);
    mMessages.setAdapter(adapter);
}


@Override
public void onLoadMore() {
    //get more messages...
    messagesArray.addAll(0, moreMessagesArray);
    adapter.notifyItemRangeInserted(0, (int) moreMessagesArray.size();
    isLoading = false;
}
Run Code Online (Sandbox Code Playgroud)

这对我来说很完美,如果服务器没有返回更多消息,则使用“totallyLoaded”来停止进行服务器调用。希望对你有帮助。


小智 0

我不依赖 onBindViewHolder 来处理这类事情。一个职位可以多次调用它。对于具有加载更多选项的列表,也许您应该在 recyclerview 膨胀后使用类似的东西。

    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            if ((((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstCompletelyVisibleItemPosition() == 0)) {
                if (args.listModel.hasMore && null != mLoadMoreCallback && !loadMoreStarted) {
                    mLoadMoreCallbacks.onLoadMore();
                }
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你。