【发布时间】:2018-08-29 11:56:25
【问题描述】:
在我的 20 个用户发布到我的 ListView 后,我试图加载更多元素(此功能运行良好),但是当我滚动到 ListView 的底部时,我想加载另外 20 个用户,但它崩溃了。
这是我到目前为止所做的
FilterData.class
private String oldestUserID;
private void fetchData(DataSnapshot dataSnapshot) {
mList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
oldestUserID = dataSnapshot.getKey();
userPojo = snapshot.getValue(UserPojo.class);
String email = userPojo.getEmail();
mList.add(email);
}
fetchSuccessListener.onListFetched(true);
}
public void refillListView(ListView listView) {
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
currentScrollState = scrollState;
isScrollCompleted();
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
currentFirstVisibleItem = firstVisibleItem;
currentVisibleItemCount = visibleItemCount;
totalItem = totalItemCount;
}
private void isScrollCompleted() {
if (totalItem - currentFirstVisibleItem == currentVisibleItemCount
&& currentScrollState == SCROLL_STATE_IDLE) {
mDatabase.orderByKey().startAt(oldestUserID).limitToFirst(20).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
fetchData(dataSnapshot);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
});
}
这就是它的工作方式,我使用一个界面来检测我的数据何时完成获取并通知我的适配器填充 ListView,这对我的前 20 个用户来说工作正常,但是当我滚动到最后时,我想要添加新用户的列表(另外 20 个),但我得到了这个崩溃日志
无法在先前设置限制的查询中调用 limitToLast!
现在,这是我调用方法以获取数据的方式
MainActivity.class
检索数据时填充列表视图的接口(工作正常)
@Override
public void onListFetched(boolean fetched) {
if(fetched){
mUserListView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
这只是为了知道用户何时滚动并需要再加载 20 个用户
filterData.refillListView(mUserListView);
我在上面尝试做的是获取数据库中的最后一个用户 ID,以便在最后一个查询后开始查询 20 个新用户,这样我可以再加载 20 个。
这是我用来获取前 20 个用户的查询
mRootDatabase = FirebaseDatabase.getInstance().getReference().child("Usuarios");
query = mRootDatabase.limitToFirst(20);
Firebase 数据库结构如下所示
编辑:Logcat 错误指向这一行
mDatabase.orderByKey().startAt(oldestUserID).limitToFirst(20).....
感谢您的帮助!
编辑:sn-p
public void refillListView() {
mQueryDatabase.orderByKey().startAt(oldestUserID).limitToFirst(20).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
fetchData(dataSnapshot);
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private Query mQueryDatabase; 与我的构造函数一起传递的位置
public FilterData(Query mQueryDatabase, Context context) {
this.mQueryDatabase = mQueryDatabase;
this.userPojo = new UserPojo();
this.mContext = context;
}
像这样填充
Query query = mRootDatabase.limitToFirst(20);
FilterData filterData = new FilterData(query,this);
oldestUserID 取自 fetchData(dataSnapshot);
fetchData 在哪里
private void fetchData(DataSnapshot dataSnapshot) {
mList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
oldestUserID = snapshot.getKey();
userPojo = snapshot.getValue(UserPojo.class);
String email = userPojo.getEmail();
mList.add(email);
}
fetchSuccessListener.onListFetched(true);
}
【问题讨论】:
-
当您在单个查询中多次调用
limitToFirst()和/或limitToLast()时会引发该错误。我从来没有见过它没有这个原因被抛出,所以这是我的第一个怀疑。您能否在不滚动的情况下重现问题,以便我可以在不需要任何 UI 的单个 sn-p 中看到问题? -
顺便说一句:在 Firebase 实时数据库上正确实现无限滚动的概念非常棒。由于 Firebase 查询不是基于偏移量的,因此大多数不熟悉 Firebase 的开发人员都对此感到很困惑。 :-)
-
嘿,非常感谢坦率,我现在就去做,让你知道
-
这就是我得到的坦率你必须结合 orderByKey() 使用 startAt(String value)、endAt(String value) 或 equalTo(String value)。不支持其他类型的值或使用带 2 个参数的版本
-
如果您可以在一个我可以复制/粘贴的 sn-p 中重现,我可以看看。现在,我错过了
mDatabase的初始化方式。通过将所有内容放在一个独立的代码中,您可以让其他人轻松地在我们的屏幕上遇到相同的问题,从而更容易看到发生了什么。这样一个所谓的MCVE(请阅读链接,它非常有用)确实是在代码相关问题上获得帮助的最佳方式。
标签: java android firebase listview firebase-realtime-database