我正在尝试实施Firebase Android聊天,仅当带有邮件的ListView滚动到显示新邮件的底部时才会更新。 (这就是聊天如何在抽搐中起作用,让用户舒服地阅读旧信息)。
这是我试过的:
MyFirebaseListAdapter (已修改的FirebaseListAdapter)
public abstract class MyFirebaseListAdapter<T> extends BaseAdapter {
...
MyFirebaseArray mSnapshots;
...
public void setShouldUpdate(boolean b) {
if (b) {
mSnapshots.addEventListener();
} else {
mSnapshots.removeEventListener();
}
}
...
}
MyFirebaseArray (已修改的FirebaseArray)
class MyFirebaseArray implements ChildEventListener {
...
private boolean hasEventListener = false;
...
public void removeEventListener() {
if (!hasEventListener) return;
hasEventListener = false;
mQuery.removeEventListener(this);
}
public void addEventListener() {
if (hasEventListener) return;
hasEventListener = true;
mSnapshots.clear();
mQuery.addChildEventListener(this);
}
...
}
ChatActivity
final MyFirebaseListAdapter adapter = new MyFirebaseListAdapter<ChatMessage>(ChatActivity.this, ChatMessage.class, R.layout.li_chat_message, db.child("/messages/" + room.key).limitToLast(40)) {
@Override
protected void populateView(View v, final ChatMessage msg, int position) {
ChatUtils.layoutChatMessage(ChatActivity.this, db, user, status, v, msg, bgColor, new View.OnLongClickListener() {
@Override
public boolean onLongClick(View view) {
etMessage.setText(msg.author.name + ", ");
return false;
}
});
}
};
lvMessages.setAdapter(adapter);
lvMessages.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) { }
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (firstVisibleItem + visibleItemCount == totalItemCount) {
adapter.setShouldUpdate(true);
} else {
adapter.setShouldUpdate(false);
}
}
});
但是,如果我在底部更改滚动方向太快,则会引发以下异常:
AndroidRuntime: FATAL EXCEPTION: main
java.lang.IndexOutOfBoundsException: Invalid index 34, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.kg.app.***.chat.adapter.MyFirebaseArray.getItem(MyFirebaseArray.java:80)
at com.kg.app.***.chat.adapter.MyFirebaseListAdapter.getItem(MyFirebaseListAdapter.java:117)
at com.kg.app.***.chat.adapter.MyFirebaseListAdapter.getView(MyFirebaseListAdapter.java:147)
at android.widget.AbsListView.obtainView(AbsListView.java:2347)
at android.widget.ListView.makeAndAddView(ListView.java:1864)
at android.widget.ListView.fillUp(ListView.java:732)
at android.widget.ListView.correctTooHigh(ListView.java:1421)
at android.widget.ListView.fillGap(ListView.java:663)
at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4995)
at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4543)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:549)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5389)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1020)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
更新
我知道抛出异常是因为我在addEventListener()方法中清除了mSnapshots数组。但是,如果我删除此行,则每次调用addEventListener时,所有记录都会重复。此外,如果我慢慢滚动我的解决方案工作正常。