David
David

Reputation: 839

Why is recycler view not showing any posts with error: E/RecyclerView: No adapter attached; skipping layout

I am using multiple queries to fill a ReceyclerView however I keep getting the error E/RecyclerView: No adapter attached; skipping layout the issue is not that I am not calling the RecyclerView in OnCreate since all of that code is in OnCreate

I have already checked that my RecyclerView is my OnCreate so it is not that.

Update:OnCreate:

 @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);

        View rootView = inflater.inflate(R.layout.fragment, container, false);
        final List<String> followingList = new ArrayList<>();
        final List<Post> postList = new ArrayList<>();
        final FollowerAdapter followerAdapter = new FollowerAdapter(postList);
        final RecyclerView recyclerView = rootView.findViewById(R.id.recycler_view);
        recyclerView.setLayoutManager(new LinearLayoutManager(this.getActivity(), RecyclerView.VERTICAL, false));
        final LinearLayoutManager linearLayoutManager = ((LinearLayoutManager) recyclerView.getLayoutManager());
        recyclerView.setAdapter(followerAdapter);

        Query first = userFollowingReference;//TODO Realtime updates
        first.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull final Task<QuerySnapshot> task) {
                if (task.isSuccessful()) {
                    for (DocumentSnapshot document : task.getResult()) {
                        String id = document.getId();
                        followingList.add(id);
                    }
                    followerAdapter.notifyDataSetChanged();
                    if(!followingList.isEmpty()) {

                        Query second = rootRef.collection("posts/" + followingList.get(0) + "/userPosts")
                                .orderBy("date", Query.Direction.ASCENDING)
                                .limit(3);
                        second.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                            @Override
                            public void onComplete(@NonNull final Task<QuerySnapshot> task) {
                                if(task.isSuccessful()) {
                                    for(DocumentSnapshot document : task.getResult()){
                                        Post post = document.toObject(Post.class);
                                        postList.add(post);
                                    }
                                    followerAdapter.notifyDataSetChanged();
                                    if(!postList.isEmpty()) {
                                        lastVisible = task.getResult().getDocuments().get(task.getResult().size() - 1);

                                        RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {
                                            @Override
                                            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                                                super.onScrollStateChanged(recyclerView, newState);
                                                if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                                                    isScrolling = true;
                                                }
                                            }

                                            @Override
                                            public void onScrolled(final RecyclerView recyclerView, int dx, int dy) {
                                                super.onScrolled(recyclerView, dx, dy);
                                                lastVisible = task.getResult().getDocuments().get(task.getResult().size() - 1);
                                                int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
                                                int visibleItemCount = linearLayoutManager.getChildCount();
                                                int totalItemCount = linearLayoutManager.getItemCount();

                                                if (isScrolling && (firstVisibleItemPosition + visibleItemCount == totalItemCount) && !isLastItemReached) {
                                                    isScrolling = false;

                                                    Query third = rootRef.collection("posts/" + followingList.get(task.getResult().size() - 1) + "/userPosts")
                                                            .orderBy("date", Query.Direction.ASCENDING)
                                                            .startAfter(lastVisible).limit(3);
                                                    third.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                                                        @Override
                                                        public void onComplete(@NonNull Task<QuerySnapshot> t) {
                                                            if (t.isSuccessful()) {
                                                                for (DocumentSnapshot d : t.getResult()) {
                                                                    Post post = d.toObject(Post.class);
                                                                    postList.add(post);
                                                                }
                                                                followerAdapter.notifyDataSetChanged();
                                                                lastVisible = task.getResult().getDocuments().get(task.getResult().size() - 1);

                                                                if (t.getResult().size() < 3) {
                                                                    isLastItemReached = true;
                                                                }
                                                            }
                                                        }
                                                    });
                                                }
                                            }
                                        };

                                        recyclerView.addOnScrollListener(onScrollListener);
                                    }
                                }

                            }
                        });
                    }
                }
            }
        });


        return rootView;

    }

Adapter:

class FollowerAdapter extends RecyclerView.Adapter<PostViewHolder> {
    private List<Post> list;

    FollowerAdapter(List<Post> list) {
        this.list = list;
    }

    @NonNull
    @Override
    public PostViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_layout, parent, false);
        return new PostViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull PostViewHolder holder, int position) {
        Post post = list.get(position);
        holder.setPost(post);
    }

    @Override
    public int getItemCount() {
        return list.size();
    }


}

When I run the app the RecyclerView is empty and I get the error:

E/RecyclerView: No adapter attached; skipping layout

Also through debugging I found that the followingList is being properly filled as is the list that holds the posts. It looks as if The RecyclerView is being skipped completely.

Edit: Here is my Firestore layout if that is helpful

Firestore-root
   |
   --- users (collection)
   |     |
   |     --- uid (documents)
   |          |
   |          --- name: "User Name"
   |          |
   |          --- email: "[email protected]"
   |
   --- following (collection)
   |      |
   |      --- uid (document)
   |           |
   |           --- userFollowing (collection)
   |                 |
   |                 --- uid (documents)
   |                 |
   |                 --- uid (documents)
   |
   --- posts (collection)
         |
         --- uid (documents)
              |
              --- userPosts (collection)
                    |
                    --- postId (documents)
                    |
                    --- postId (documents)

Thank you so far for everyone's help!

Update: I am now able to see several posts but after scrolling to the bottom of the RecyclerView I get java.lang.IndexOutOfBoundsException Bellow is my Logcat:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.android, 
    java.lang.IndexOutOfBoundsException: Invalid index 2, size is 1
        at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
        at java.util.ArrayList.get(ArrayList.java:308)
        at com.example.android.Fragments.FollowingFragment$1$1$1.onScrolled(FollowingFragment.java:104)
        at androidx.recyclerview.widget.RecyclerView.dispatchOnScrolled(RecyclerView.java:5077)
        at androidx.recyclerview.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:5241)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
        at android.view.Choreographer.doCallbacks(Choreographer.java:580)
        at android.view.Choreographer.doFrame(Choreographer.java:549)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5343)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)

Upvotes: 0

Views: 79

Answers (3)

Sammy T
Sammy T

Reputation: 1924

It seems that it's not finding any data on your RecyclerView on its initial layout pass. You should move your adapter set up outside of your OnCompleteListener then update the data from within it:

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

    // Your set up/initialization

    recyclerView.setAdapter(yourAdapter);

    first.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull final Task<QuerySnapshot> task){
            // Update your adapter and notifyDataSetChanged when needed here
        }
    }
}

Upvotes: 1

Ashok Kumar
Ashok Kumar

Reputation: 1271

followerAdapter is passed with postlist , it should be followinglist.

Also in query2 postlist is currently not updating with fetched data

Upvotes: 1

Wesely
Wesely

Reputation: 1475

Suppose your data-parts are fine,

RecyclerView needs these to display the content.

recyclerView.setLayoutManager(linearLayoutManager) // ?
recyclerView.setAdapter(...)

Make sure you call these method properly, and you can update if there's still problems.


Update:

I think your onComplete is not on the mainThread.

make sure you call recyclerView.setAdapter(followerAdapter); from MainThread.

in fact you can put setLayoutManager and setAdapter in onCreateView() stage, just call notifyDataSetChanged in your onComplete().

Upvotes: 1

Related Questions