【问题标题】:ListView scrolls to top after updating itListView 更新后滚动到顶部
【发布时间】:2018-02-24 16:35:32
【问题描述】:

我有一个 mChildEventListener 查询来自 Firebase Database 的前 n 个项目和另一个 mChildEventListener2(当用户向上滚动并单击 Load More 按钮时触发)查询对于接下来的 n 项,并将它们添加到 ChatMessagesList

当用户单击Load More 按钮时:ChatMessagesList 被更新,notifyDataSetChanged 被调用。 mMessageListView 已更新,但每次都会向下滚动到底部。由于 xml 属性,我解释了这种行为:android:transcriptMode="alwaysScroll"

当我删除transcriptMode="alwaysScroll" 并且用户按下Load More 按钮时,mMessageListView 这次滚动到顶部。

这些行为都不是我们想要的。我希望当用户按下按钮时,mMessageListView 将保持其滚动位置。 (原因很明显)

我尝试从新线程调用notifyDataSetChanged。没有结果。

我尝试使用listView.setSelectionFromTop(lastViewedPosition, topOffset);list.smoothScrollToPosition();,但都没有达到我想要的流畅体验。

mMessageListView更新后如何保持滚动位置?

这是代码:

private ChildEventListener mChildEventListener;
private ChildEventListener mChildEventListener2;

List<ChatMessage> ChatMessages = new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
      ...
mMessageAdapter = new MessageAdapter(this, R.layout.item_message_sent, ChatMessages);
mMessageListView.setAdapter(mMessageAdapter);

 mChildEventListener = new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                if(i == 0) {
                    current_last_key = dataSnapshot.getKey();
                }
                else {
                    ChatMessage chatMessage = dataSnapshot.getValue(ChatMessage.class);
                    mMessageAdapter.add(chatMessage);
                }
                i++;
            }
          ...
        };
        Query messagesQuery =  mDatabaseReference.child("chat_messages").
                child(chatId).limitToLast(25);
        messagesQuery.addChildEventListener(mChildEventListener);
          ...
   }

 @Override
public void onClick(View v) {
    j = 0;
    mChildEventListener2 = new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            if(!dataSnapshot.getKey().equals(current_last_key)) {
                if (j == 0) {
                    current_last_key = dataSnapshot.getKey();
                }
                else {
                    ChatMessage chatMessage = dataSnapshot.getValue(ChatMessage.class);
                    ChatMessages.add(j- 1, chatMessage);
                }

            }
            else
            {
                ChatMessage chatMessage = dataSnapshot.getValue(ChatMessage.class);
                ChatMessages.add(0 , chatMessage);
                loadMoreTextView.setVisibility(View.GONE);
            }
            mMessageAdapter.notifyDataSetChanged();
            j++;
        }

        ...        };
    Query query = mDatabaseReference.child("chat_messages").
            child(chatId).orderByKey().endAt(current_last_key).limitToLast(10);
    query.addChildEventListener(mChildEventListener2);
}

【问题讨论】:

    标签: android listview scroll autoscroll


    【解决方案1】:
    notifyDataSetChanged()
    

    通知附加的观察者底层数据已更改,任何反映数据集的视图都应自行刷新。

    尝试更新时是否再次调用“onCreate()”

    【讨论】:

    • 我没有看到相关性。请详细说明
    【解决方案2】:

    FirebaseUI lib 为您处理所有这些并简化您的代码。 顺便说一句,您可以使用 mAdapter.notifyItemInserted(ChatMessages.size() - 1);mMessageAdapter.notifyItemRangeInserted(ChatMessages.size() - 1, ChatMessages.size() - 1 + numberOfItemsBeingInserted); 并进行其他必要的更改以使其正常工作,而不是使用 mMessageAdapter.notifyDataSetChanged();

    【讨论】:

    • 你的意思是 FirebaseUI 库处理数据分页?
    • 是的!只需使用FirebaseIndexRecyclerAdapter(Class&lt;T&gt; modelClass, @LayoutRes int modelLayout, Class&lt;VH&gt; viewHolderClass, Query keyQuery, DatabaseReference dataRef) 构造函数而不是FirebaseRecyclerAdapter&lt;Food, FoodCardViewHolder&gt;( Food.class, R.layout.card_view_food, FoodCardViewHolder.class, foodInfoRef)
    • 不过,使用 FirebaseIndexRecyclerAdapter 需要我索引我的 ChatMessages ,这是我避免的事情。我已经对我的数据进行了分页,我只是遇到了ListView 的问题
    猜你喜欢
    • 2012-08-06
    • 2011-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多