Array List becomes empty after addListenerForSingleValueEvent listener method

核能气质少年 提交于 2021-01-28 10:59:37

问题


I am fetching data from firebase database to a recyclerview. I can't get the data to the RecyclerViewAdapter since the Array list becomes empty after the addListenerForSingleValueEvent method.

@Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View view = inflater.inflate(R.layout.fragment_dashboard, container, false);
        database = FirebaseDatabase.getInstance();
        ArrayList<Item> arr = new ArrayList<Item>();


        DatabaseReference reference = database.getReference("NoticeBoard");

        reference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                for (DataSnapshot singleSnapshot : dataSnapshot.getChildren()) {

                    String text1 = (String) singleSnapshot.child("Text1").getValue();
                    String text2 = (String) singleSnapshot.child("Text2").getValue();

                    arr.add(new Item(text1, text2));
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });

        RecyclerViewAdapter adapter = new RecyclerViewAdapter(getContext(), arr);// Here the ArrayList arr is empty

        RecyclerView recyclerView = view.findViewById(R.id.dashboardRecyclerView);

        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.setAdapter(adapter);

        return view;
    }

回答1:


onDataChange() is asynchronous therefore since you are calling the arraylist after addListenerForSingleValueEvent, it will return an empty list because the data is not yet retrieved.

To solve your problem, you need to add the arrayList inside onDatachange():

        reference.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

                for (DataSnapshot singleSnapshot : dataSnapshot.getChildren()) {

                    String text1 = (String) singleSnapshot.child("Text1").getValue();
                    String text2 = (String) singleSnapshot.child("Text2").getValue();
                    ArrayList<Item> arr = new ArrayList<Item>();
                    arr.add(new Item(text1, text2));

                    RecyclerViewAdapter adapter = new RecyclerViewAdapter(getContext(), arr);
                    RecyclerView recyclerView = view.findViewById(R.id.dashboardRecyclerView);

                    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
                    recyclerView.setAdapter(adapter);
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
            }
        });



回答2:


Firebase database calls are not asynchronous means the lines below query will be executed before you are getting response from firebase.

So update your code as below to work as expected.

 RecyclerViewAdapter adapter;

 @Override
 public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View view = inflater.inflate(R.layout.fragment_dashboard, container, false);
    database = FirebaseDatabase.getInstance();
    ArrayList<Item> arr = new ArrayList<Item>();

    adapter = new RecyclerViewAdapter(getContext(), arr);// Here the ArrayList arr is empty

    RecyclerView recyclerView = view.findViewById(R.id.dashboardRecyclerView);

    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    recyclerView.setAdapter(adapter);

    DatabaseReference reference = database.getReference("NoticeBoard");

    reference.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {

            for (DataSnapshot singleSnapshot : dataSnapshot.getChildren()) {

                String text1 = (String) singleSnapshot.child("Text1").getValue();
                String text2 = (String) singleSnapshot.child("Text2").getValue();

                arr.add(new Item(text1, text2));
            }
            if(adapter != null){
               adapter.notifyDataSetChanged();
            }
        }
        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {
        }
    });

    return view;
}

Notes: It is good practice to set data after view has been created in fragments. You can use onViewCreated() method of fragment for that.



来源:https://stackoverflow.com/questions/56747595/array-list-becomes-empty-after-addlistenerforsinglevalueevent-listener-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!