【问题标题】:ArrayList becomes null after addValueEventListeneraddValueEventListener 后 ArrayList 变为 null
【发布时间】:2019-07-11 09:01:25
【问题描述】:

我试图在 RecyclerView 中显示一些项目,这些项目包含在填充有 RealtimeDatabase (Firebase) 数据的 ArrayList 中。每次在数据库中检测到一些更改时都会执行此操作,如下所示。问题是lstCompanyaddValueEventListener 之后很快变为空。我怎样才能让它实现?

public class FragmentCompanies extends Fragment {
    View v;
    private RecyclerView recyclerView;
    private List<Company> lstCompany;
    DatabaseReference db;

    public FragmentCompanies(){}

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        db = FirebaseDatabase.getInstance().getReference();
        db.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                lstCompany = new ArrayList<>();
                DataSnapshot ds = dataSnapshot.child("Company");
                for (DataSnapshot company: ds.getChildren()){
                    Map<String, String> currCompany = (Map) company.getValue();
                    Company c = new Company(currCompany.get("name"), currCompany.get("overview"), currCompany.get("imageURL"));
                    lstCompany.add(c);
                    System.out.println(lstCompany);
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
        System.out.println(lstCompany);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){
        v = inflater.inflate(R.layout.fragment_companies,container,false);

        System.out.println(lstCompany);

        //bind the adapter to the recyclerView
        recyclerView = v.findViewById(R.id.companies_recyclerview);
        CompaniesRecyAdapter recyAdapter = new CompaniesRecyAdapter(getContext(), lstCompany);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setAdapter(recyAdapter);

        return v;
    }
}

最后两个 println 操作返回 null,它不应该发生。

【问题讨论】:

  • 这是一个回调。 lstCompany 在您的 ValueEventListener 之外为空,因为尚未调用 onDataChange
  • 是的,感谢您的解释。但是,每次数据库中的数据发生变化时,如何让 RecyclerView 更新呢?考虑到由于 Firebase db 需要回调...
  • 您不能从onDataChange 调用您需要的任何更新吗?这就是回调的用途......

标签: java android arrays arraylist


【解决方案1】:

在onCreate中初始化arraylist,并在onDataChange中添加数据时通知适配器数据已更改

public class FragmentCompanies extends Fragment {
    View v;
    private RecyclerView recyclerView;
    private List<Company> lstCompany;
    DatabaseReference db;
    public FragmentCompanies(){}

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){
        v = inflater.inflate(R.layout.fragment_companies,container,false);

        lstCompany = new ArrayList<>();
        System.out.println(lstCompany);

        //bind the adapter to the recyclerView
        recyclerView = v.findViewById(R.id.companies_recyclerview);
        CompaniesRecyAdapter recyAdapter = new CompaniesRecyAdapter(getContext(), lstCompany);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setAdapter(recyAdapter);

        db = FirebaseDatabase.getInstance().getReference();
        db.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                DataSnapshot ds = dataSnapshot.child("Company");
                for (DataSnapshot company: ds.getChildren()){
                    Map<String, String> currCompany = (Map) company.getValue();
                    Company c = new Company(currCompany.get("name"), currCompany.get("overview"), currCompany.get("imageURL"));
                    lstCompany.add(c);
                    System.out.println(lstCompany);
                    System.out.println(c.getCompanyName);
                }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
        System.out.println(lstCompany);





        return v;
    }
}

【讨论】:

  • 现在最后两个打印返回 []
  • 尝试打印它的大小 lstCompany.size() 你不能打印这样的列表
  • size 明显是0
  • 在 for 循环内尝试打印 c.compantname,如果它正在打印任何内容,则运行
  • 我只是在for循环之后添加了适配器的通知操作,它似乎有效(我知道它是在开头写的,但我误解了这句话,因为这是我第一次处理RecyclerViews.. .)。谢谢!
猜你喜欢
  • 2013-12-29
  • 2017-09-13
  • 1970-01-01
  • 1970-01-01
  • 2019-06-12
  • 1970-01-01
  • 1970-01-01
  • 2020-10-17
  • 2020-11-11
相关资源
最近更新 更多