androidandroid-recyclerviewgoogle-cloud-firestoreandroid-tabbed-activity

RecyclerView: No adapter attached skipping layout (TabbedActivity + Firestore)


I am trying to retrieve data from firestore and display it as a RecyclerView within a TabbedActivity. The data is displaying in each tab/fragment, but sometimes if i swipe forwards through the tabs and then back the data disappears and the error "No adapter attached skipping layout" appears.

Fragment.java

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

    recyclerView = (RecyclerView) v.findViewById(R.id.sligo_recycler);
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    return v;
}

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

    db.collection("sligo")
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    for (QueryDocumentSnapshot document : task.getResult()) {
                        placeNames.add(document.getData().get("Name").toString());
                    }
                    MyAdapter adapter = new MyAdapter(placeNames);
                    recyclerView.setAdapter(adapter);
                }
            });
}

MyAdapter.java

public static class MyViewHolder extends RecyclerView.ViewHolder{
    public TextView textView;
    public MyViewHolder(View itemView) {
        super(itemView);
        textView = itemView.findViewById(R.id.info_text);
    }
}

public MyAdapter(ArrayList<String> myDataset) {

    mDataset = myDataset;
}


@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    // create a new view
    View v =  LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item, parent, false);
    MyViewHolder vh = new MyViewHolder(v);
    return vh;

}

Solution

  • According Fragment LifeCycle onCreate is called before onCreateView. Beside this you are setting adapter inside asynchronous operation which takes time to complete. Try to move the code to onCreateView like below:

    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        v = inflater.inflate(R.layout.sligo_fragment, container, false);
    
        recyclerView = (RecyclerView) v.findViewById(R.id.sligo_recycler);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        MyAdapter adapter = new MyAdapter(placeNames);
        recyclerView.setAdapter(adapter);
    
        db.collection("sligo")
                .get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        for (QueryDocumentSnapshot document : task.getResult()) {
                            placeNames.add(document.getData().get("Name").toString());
                        }
    
                        adapter.notifyDataSetChanged();
                    }
                });
    
        return v;
    }