插入新元素时 RecyclerView 以错误的方向滚动
RecyclerView scroll in incorrect direction when new element is inserted
我使用 smoothScrollToPosition
滚动 RecyclerView。每次插入新条目时它都会滚动;但是到顶部,而不是到底部,这是我想要的方向。
list_chat = (RecyclerView) findViewById(R.id.list_chat);
//Set up Layout Manager
linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setStackFromEnd(true);
list_chat.setLayoutManager(linearLayoutManager);
//set adapter
list_chat.setAdapter(adapter);
//set scroll
list_chat.post(new Runnable() {
@Override
public void run() {
list_chat.smoothScrollToPosition(adapter.getItemCount());
}
});
适配器来自 Firebase
adapter = new FirebaseRecyclerAdapter<ChatItem, ChatRecylerViewHolder>(ChatItem.class,R.layout.chat_item
,ChatRecylerViewHolder.class,queryChat ) {
@Override
protected void populateViewHolder(ChatRecylerViewHolder viewHolder, ChatItem model, int position) {
viewHolder.tvAuthorChat.setText(model.chatAuthor);
viewHolder.tvContentChat.setText(model.chatContent);
}
};
您注意到您正在使用 linearLayoutManager.setStackFromEnd(true);
这意味着您的第一个位置在底部。我建议你一个更好的选择。
RecycleView 不像 listView 那样工作,你可以用你的布局管理器滚动它,像这样
linearLayoutManager.scrollToPositionWithOffset(position,offset);
which position是你要滚动到的位置,offset是在当前位置的偏移量。您也可以只使用一个参数。
linearLayoutManager.scrollToPosition(position);
好的。我找到了答案。
首先,我的问题的老问题:我认为每当插入一个项目时都会调用 list_chat.post
(事实证明这是错误的)。它一直滚动到顶部的原因是 linearLayoutManager.setStackFromEnd(true);
因此,问题归结为 在哪里调用滚动?
答案是:由于适配器管理数据,所以猜测适配器会通知插入是有道理的。
这是代码
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
list_chat.smoothScrollToPosition(adapter.getItemCount());
}
});
我使用 smoothScrollToPosition
滚动 RecyclerView。每次插入新条目时它都会滚动;但是到顶部,而不是到底部,这是我想要的方向。
list_chat = (RecyclerView) findViewById(R.id.list_chat);
//Set up Layout Manager
linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setStackFromEnd(true);
list_chat.setLayoutManager(linearLayoutManager);
//set adapter
list_chat.setAdapter(adapter);
//set scroll
list_chat.post(new Runnable() {
@Override
public void run() {
list_chat.smoothScrollToPosition(adapter.getItemCount());
}
});
适配器来自 Firebase
adapter = new FirebaseRecyclerAdapter<ChatItem, ChatRecylerViewHolder>(ChatItem.class,R.layout.chat_item
,ChatRecylerViewHolder.class,queryChat ) {
@Override
protected void populateViewHolder(ChatRecylerViewHolder viewHolder, ChatItem model, int position) {
viewHolder.tvAuthorChat.setText(model.chatAuthor);
viewHolder.tvContentChat.setText(model.chatContent);
}
};
您注意到您正在使用 linearLayoutManager.setStackFromEnd(true);
这意味着您的第一个位置在底部。我建议你一个更好的选择。
RecycleView 不像 listView 那样工作,你可以用你的布局管理器滚动它,像这样
linearLayoutManager.scrollToPositionWithOffset(position,offset);
which position是你要滚动到的位置,offset是在当前位置的偏移量。您也可以只使用一个参数。
linearLayoutManager.scrollToPosition(position);
好的。我找到了答案。
首先,我的问题的老问题:我认为每当插入一个项目时都会调用 list_chat.post
(事实证明这是错误的)。它一直滚动到顶部的原因是 linearLayoutManager.setStackFromEnd(true);
因此,问题归结为 在哪里调用滚动?
答案是:由于适配器管理数据,所以猜测适配器会通知插入是有道理的。
这是代码
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
list_chat.smoothScrollToPosition(adapter.getItemCount());
}
});