我正在将数据从云firestore
加载到自定义的recyclerview适配器中。根据我的日志,我从firestore
获得的数据很好,并且在我的get方法内部,日志显示列表大小在增加。在我的get方法之外, mWorkoutList 返回大小为0。我不知道为什么会这样。
public class ViewWorkoutsActivity extends AppCompatActivity implements WorkoutAdapter.WorkoutAdapterOnClickHandler {
private final String TAG = this.getClass().getName();
private FirebaseFirestore db;
private String mUid;
private List<Set> mSetList;
private RecyclerView mRecyclerView;
private WorkoutAdapter mWorkoutAdapter;
private List<OtherWorkout> mWorkoutList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_workouts);
mWorkoutList = new ArrayList<>();
mUid = getIntent().getStringExtra("uid");
db = FirebaseFirestore.getInstance();
initDatabaseData();
mRecyclerView = findViewById(R.id.recycler_view);
LinearLayoutManager linearLayoutManager
= new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setHasFixedSize(true);
mWorkoutAdapter = new WorkoutAdapter(this);
mRecyclerView.setAdapter(mWorkoutAdapter);
Log.i("LOG", "workout list size HERE: " + mWorkoutList.size());
mWorkoutAdapter.setWorkoutData(mWorkoutList);
}
@Override
public void onClick(OtherWorkout workout) {
}
public void initDatabaseData(){
CollectionReference collectionReference2 = db.collection("users").document(mUid).collection("workouts");
collectionReference2.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if(task.isSuccessful()){
for (QueryDocumentSnapshot document : task.getResult()){
OtherWorkout workout = document.toObject(OtherWorkout.class);
mWorkoutList.add(workout);
Log.i("LOG", "workout list size: " + mWorkoutList.size());
}
}
}
});
}
}
答案 0 :(得分:2)
您好,艾伦,您正在调用initDatabaseData();在oncreate()方法中,该方法发出网络请求并获取数据。因此,大约需要2-3秒来获取数据。但是在这2-3秒内,您在initDatabaseData()下的代码被调用
LinearLayoutManager linearLayoutManager
= new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(linearLayoutManager);
mRecyclerView.setHasFixedSize(true);
mWorkoutAdapter = new WorkoutAdapter(this);
mRecyclerView.setAdapter(mWorkoutAdapter);
Log.i("LOG", "workout list size HERE: " + mWorkoutList.size());
mWorkoutAdapter.setWorkoutData(mWorkoutList);
因此,直到数据还没有到,列表大小将显示为0,然后在onComplete()中获取数据后,列表大小将增加()。因此,基本上添加一行mWorkoutAdapter.notifyDatasetChanged();在这里:-
if(task.isSuccessful()){
for (QueryDocumentSnapshot document : task.getResult()){
OtherWorkout workout = document.toObject(OtherWorkout.class);
mWorkoutList.add(workout);
Log.i("LOG", "workout list size: " + mWorkoutList.size());
}mWorkoutAdapter.notifyDatasetChanged();
}
这将使用新值刷新适配器。
答案 1 :(得分:0)
您将OtherWorkout
创建为本地对象,然后将其添加到集合中。
如果您的get()
函数超出范围,则该对象将被自动删除。
我没有检查,但是我认为Java垃圾回收将处理其余工作并从Array中删除对象。
您应使用new
在堆上创建对象,以使它们在该函数范围之外仍然存在。
答案 2 :(得分:0)
您可以检查您的
Log.i("LOG", "workout list size: " + mWorkoutList.size());
之后
Log.i("LOG", "workout list size HERE: " + mWorkoutList.size());
所以这意味着firebase需要一些时间来获取所有数据,在这段时间内您的其余代码将被执行。 因此,在设置适配器之后,该解决方案称为initDatabaseData(),然后调用adapter.notifydatasetchanged()。或者您也可以在获取数据后直接通过initDatabaseData()方法通知适配器。
答案 3 :(得分:0)
addOnCompleteListener
提供了一种添加异步任务侦听器的方法。
调用initDatabaseData()
时,将启动任务并定义一个侦听器。但是不能保证从initDatabaseData
返回时此任务已完成。
这就是为什么一旦在mWorkoutList
方法中打印了onCreate
大小后,该值便可能与侦听器中打印的值不同。
为避免这种情况,您可以通过将异步机制更改为同步机制,也可以通过使用侦听器onComplete
方法的数据部分来更改程序的工作方式