【问题标题】:How to populate ArrayList inside onDataChange , arraylist being used to update Adapter如何在 onDataChange 中填充 ArrayList,arraylist 用于更新适配器
【发布时间】:2020-08-18 22:27:01
【问题描述】:

我陷入了困境,我必须通过 FirebaseRealtimeDatabase 填充 ArrayList,现在这会返回一个 ViewHolder,但由于 onDataChange 是异步的,因此在 onDataChange 完成数据填充之前调用 getItemSize(),导致它返回0,因此永远不会调用 onCreateViewHoldwer。如何让 Adapter 等到从 onDataChange 获取所有数据或通知 Adapter 它需要刷新? 注意:这一切都发生在 Adapter 类中。

我尝试实现一个回调,但该回调也在 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()

}

【问题讨论】:

    标签: java firebase firebase-realtime-database android-asynctask asynccallback


    【解决方案1】:

    您不能让适配器等待异步操作。您可以推迟创建适配器(从而将加载数据的代码移到适配器之外),或者让适配器处理其数据是异步加载的事实。

    后者通过在数据加载时通知适配器来实现:

    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
        }
    });
    

    【讨论】:

    • 当我使用你的代码时,适配器没有称为 notifyDataSetChanged() 的方法,它有 notify()?我在 populateLisy() 中声明适配器,我犯了一些错误吗?
    • 如果我们通过向 main activiy 发送回调来做同样的事情,这种方法是否有一些优势?
    • 我看到你接受了我的回答,所以假设你发现了你的回调和notifyDataSetChanged() 之间的区别:后者通知适配器它需要重新绘制它附加到的任何视图。
    猜你喜欢
    • 2021-04-25
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    • 2015-03-28
    • 1970-01-01
    • 1970-01-01
    • 2010-11-20
    • 2017-12-29
    相关资源
    最近更新 更多