如何在 onDataChange 中填充 ArrayList,arraylist 用于更新 Adapter
How to populate ArrayList inside onDataChange , arraylist being used to update Adapter
我遇到了一种情况,我必须通过 FirebaseRealtimeDatabase 填充 ArrayList,现在这个 returns 一个 ViewHolder,但是由于 onDataChange 是异步的,所以在 onDataChange 完成数据之前调用 getItemSize() population,导致它变为 returns 0,因此永远不会调用 onCreateViewHoldwer。如何让 Adapter 等到从 onDataChange 获取所有数据,或者通知 Adapter 它需要刷新?
注意:这一切都发生在 Adapter class.
内部
我尝试实现回调,但在 getItemSize() 之后也会调用该回调
这是我的代码的最小亮点
public class SubjectAdapter extends RecyclerView.Adapter<SubjectHolder> {
public interface MyCallback{
void onCallback(Subjects s);
}
//declarations
public SubjectAdapter(Context context) {
//initialisations
populateList(new MyCallback() {
@Override
public void onCallback(Subjects s) {
subjectsArrayList.add(s);
Log.e("callback",s.toString());
}
});
mContext=context;
}
public void populateList(final MyCallback myCallback){
final ArrayList<String> units=new ArrayList<String>();
semesterInfoReference.child("1").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot dsa:dataSnapshot.getChildren()) {
//Log.e("dsa",dsa.getValue().toString());
String subjectCode = dsa.getKey();
for(DataSnapshot ds:dsa.getChildren()) {
SubjectObj subjectObj = ds.getValue(SubjectObj.class);
units.add("Unit I");units.add("Unit II");
units.add("Unit III");units.add("Unit IV");
Subjects s = new Subjects(subjectObj.getProfessorName(), subjectCode, subjectObj.getSubjectName(), units);
myCallback.onCallback(s);
//subjectsArrayList.add(s);
//Log.e("subjectArrayLIst", subjectsArrayList.toString());
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
Log.e("holder", String.valueOf(subjectsArrayList.size()));
}
@Override
public void onBindViewHolder(@NonNull SubjectHolder holder, int position, @NonNull List payloads) {
super.onBindViewHolder(holder, position, payloads);
}
@NonNull
@Override
public SubjectHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//something
}
@Override
public void onBindViewHolder(@NonNull SubjectHolder holder, int position) {
//something
}
@Override
public int getItemCount()
}
您不能让适配器等待异步操作。您可以推迟创建适配器(从而将加载数据的代码移到适配器外部),或者让适配器处理其数据异步加载的事实。
后者通过在数据加载时通知适配器来完成:
SubjectAdapter adapter = this;
semesterInfoReference.child("1").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot dsa:dataSnapshot.getChildren()) {
//Log.e("dsa",dsa.getValue().toString());
String subjectCode = dsa.getKey();
for(DataSnapshot ds:dsa.getChildren()) {
SubjectObj subjectObj = ds.getValue(SubjectObj.class);
units.add("Unit I");units.add("Unit II");
units.add("Unit III");units.add("Unit IV");
Subjects s = new Subjects(subjectObj.getProfessorName(), subjectCode, subjectObj.getSubjectName(), units);
myCallback.onCallback(s);
}
adapter.notifyDataSetChanged();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException(); // never ignore errors
}
});
我遇到了一种情况,我必须通过 FirebaseRealtimeDatabase 填充 ArrayList,现在这个 returns 一个 ViewHolder,但是由于 onDataChange 是异步的,所以在 onDataChange 完成数据之前调用 getItemSize() population,导致它变为 returns 0,因此永远不会调用 onCreateViewHoldwer。如何让 Adapter 等到从 onDataChange 获取所有数据,或者通知 Adapter 它需要刷新? 注意:这一切都发生在 Adapter class.
内部我尝试实现回调,但在 getItemSize() 之后也会调用该回调
这是我的代码的最小亮点
public class SubjectAdapter extends RecyclerView.Adapter<SubjectHolder> {
public interface MyCallback{
void onCallback(Subjects s);
}
//declarations
public SubjectAdapter(Context context) {
//initialisations
populateList(new MyCallback() {
@Override
public void onCallback(Subjects s) {
subjectsArrayList.add(s);
Log.e("callback",s.toString());
}
});
mContext=context;
}
public void populateList(final MyCallback myCallback){
final ArrayList<String> units=new ArrayList<String>();
semesterInfoReference.child("1").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot dsa:dataSnapshot.getChildren()) {
//Log.e("dsa",dsa.getValue().toString());
String subjectCode = dsa.getKey();
for(DataSnapshot ds:dsa.getChildren()) {
SubjectObj subjectObj = ds.getValue(SubjectObj.class);
units.add("Unit I");units.add("Unit II");
units.add("Unit III");units.add("Unit IV");
Subjects s = new Subjects(subjectObj.getProfessorName(), subjectCode, subjectObj.getSubjectName(), units);
myCallback.onCallback(s);
//subjectsArrayList.add(s);
//Log.e("subjectArrayLIst", subjectsArrayList.toString());
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
Log.e("holder", String.valueOf(subjectsArrayList.size()));
}
@Override
public void onBindViewHolder(@NonNull SubjectHolder holder, int position, @NonNull List payloads) {
super.onBindViewHolder(holder, position, payloads);
}
@NonNull
@Override
public SubjectHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//something
}
@Override
public void onBindViewHolder(@NonNull SubjectHolder holder, int position) {
//something
}
@Override
public int getItemCount()
}
您不能让适配器等待异步操作。您可以推迟创建适配器(从而将加载数据的代码移到适配器外部),或者让适配器处理其数据异步加载的事实。
后者通过在数据加载时通知适配器来完成:
SubjectAdapter adapter = this;
semesterInfoReference.child("1").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot dsa:dataSnapshot.getChildren()) {
//Log.e("dsa",dsa.getValue().toString());
String subjectCode = dsa.getKey();
for(DataSnapshot ds:dsa.getChildren()) {
SubjectObj subjectObj = ds.getValue(SubjectObj.class);
units.add("Unit I");units.add("Unit II");
units.add("Unit III");units.add("Unit IV");
Subjects s = new Subjects(subjectObj.getProfessorName(), subjectCode, subjectObj.getSubjectName(), units);
myCallback.onCallback(s);
}
adapter.notifyDataSetChanged();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException(); // never ignore errors
}
});