简体   繁体   English

ArrayList从Firebase数组适配器返回null

[英]ArrayList returning null from firebase array adapter

I'm trying to add the data that I got from the datasnapshot into an arraylist but it keeps returning null . 我试图将我从datasnapshot获得的数据添加到arraylist但它始终返回null I know I should be doing any changes to UI inside of this method however I need to be able to access this outside of the method so I can return the value back to my fragment. 我知道我应该对此方法内部的UI进行任何更改,但是我需要能够在方法外部进行访问,以便可以将值返回到片段中。

I have added print statements inside the datasnapshot and I can see that I am getting the data I need however outside of the scope of the @Override function it remains empty. 我在datasnapshot内添加了print语句,可以看到我正在获取所需的数据,但是在@Override函数范围之外,它仍然为空。 I need a way to access this globally to send to my arrayAdapter and return my other activity which implements this fragment. 我需要一种全局访问此方法的方法,以发送到我的arrayAdapter并返回实现此片段的其他活动。 Please help. 请帮忙。

public class YourTripTab extends Fragment {

    private DatabaseReference userReference;
    private String userID;
    private String Tag = "YourTripTab";
    private List<Trip> trips = new ArrayList<>();

    public void setUserID(String userID) {
        this.userID = userID;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View tripView = inflater.inflate(R.layout.your_trips, container, false);

        userReference = FirebaseDatabase.getInstance().getReference("userTrips").child(userID);

        //find Id from xml file
        ListView tripListView = (ListView) tripView.findViewById(R.id.trips);

        //create our TripListAdapter array adapter
        TripListAdapter tripListAdapter = new TripListAdapter(getContext(), retrieve());

        tripListView.setAdapter(tripListAdapter);

        return tripView;

    }

    public List<Trip> retrieve() {

        userReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {
                    for (DataSnapshot ds : dataSnapshot.getChildren()) {
                        String startDate = ds.child("startDate").getValue().toString();
                        String tripName = ds.child("tripName").getValue().toString();
                        System.out.println("Trip Name:~ " + ds.getKey() + ":: startDate here ~ " + startDate + "//" + "tripName ~ " + tripName);
                        trips.add(new Trip(tripName, startDate));
                    }
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                //no data exists or error getting data
            }

        });

        System.out.println("Here is the size of trips list: " + trips.size());

        return trips;
    }

}

EDIT 编辑

I managed to fix it here is the solution 我设法解决这里是解决方案

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {


        final View tripView = inflater.inflate(R.layout.your_trips, container, false);



        getData(new FirebaseCallback() {
            @Override
            public void onCallBack(List<Trip> list) {
                for(int i = 0; i < list.size(); i++){
                    trips.add(list.get(i));
                }
                tripListView = (ListView) tripView.findViewById(R.id.trips);
                tripListAdapter = new TripListAdapter(getContext(), trips);
                tripListView.setAdapter(tripListAdapter);
            }
        });



        return tripView;

    }


    private interface FirebaseCallback {

        void onCallBack(List<Trip> list);

    }


    private void getData(final FirebaseCallback firebaseCallback) {

        userReference = FirebaseDatabase.getInstance().getReference("userTrips").child(userID);
        userReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {
                    List<Trip> tempList = new ArrayList<>();
                    System.out.println("dataSnapshot is here: " + dataSnapshot);

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

                        String startDate = snapshot.child("startDate").getValue().toString();
                        String tripName = snapshot.child("tripName").getValue().toString();
                        System.out.println("startDate here: " + startDate + "\n" + "tripName: " + tripName);
                        tempList.add(new Trip(tripName, startDate));

                    }

                    firebaseCallback.onCallBack(tempList);
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

    }```


addValueEventListener is asynchronous and returns immediately. addValueEventListener是异步的,并立即返回。 The callback you passed to it will get invoked some unknown amount of time later, whenever the data is available. 每当有数据可用时,传递给它的回调将在未知的时间内被调用。 This means that your retrieve method also returns immediately with the initial value of trips , which is empty. 这意味着您的retrieve方法还立即返回trips的初始值,该初始值为空。 To state this another way - the first time retrieve is called, it returns an empty List of Trip objects. 为了说明这一点的另一种方式-在第一时间retrieve被调用时,它返回旅行对象的空列表。

If you want your ListView to show data, you should instead set its adapter after you've collected all this trips. 如果希望ListView显示数据,则应在收集所有行程设置其适配器。 This means you should do it inside the addValueEventListener callback. 这意味着您应该在addValueEventListener回调中执行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM