''RecyclerView: No adapter attached; skipping layout' error when nesting RecyclerView alongside EditText inside parent layout

I have a RecyclerView which correctly displays data gotten from an RSS feed when it is the sole object within the XML file, i.e. it is not nested in a parent or sharing a parent within another element. Conversely, when I try to do just that, the data does not display, and I instead receive the error 'RecyclerView: No adapter attached; skipping layout' in LogCat. I should mention that this RecyclerView is generated as part of a ListFragment.

The Fragment replaces a FrameLayout in ActivityMain.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?actionBarSize"
            android:background="@color/design_default_color_primary"
            android:elevation="4dp"
            android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:titleTextColor="#ffff"/>
        <!-- This one -->
        <FrameLayout
            android:id="@+id/main_fragment_target"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </LinearLayout>

    <com.google.android.material.navigation.NavigationView
        android:id= "@+id/nav_view"
        android:layout_width= "wrap_content"
        android:layout_height= "match_parent"
        android:layout_gravity= "start"
        android:fitsSystemWindows= "true"
        app:menu= "@menu/activity_main_drawer" />

</androidx.drawerlayout.widget.DrawerLayout>

Which is performed by the following code in MainActivity.java

            MainActivity.this.runOnUiThread(() -> {
                FragmentManager manager = getSupportFragmentManager();
                FragmentTransaction transaction = manager.beginTransaction();
                transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
                ComponentListFragment componentListFragment = new ComponentListFragment(componentsList);
                transaction.replace(R.id.main_fragment_target, componentListFragment);
                transaction.commit();
            });

As mentioned, the data loads just fine when I'm not messing with the RecycleView XML file, so I am doubtful that inserting the fragment is the problem. I'm just posting this for posterity.

So, MainActivity.java replaces the fragment with an instance of ComponentListFragment.java:

package com.example.mclean_ross_s2030507;

import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

/**
 * A fragment representing a list of Items.
 */
public class ComponentListFragment extends Fragment {

    // TODO: Customize parameter argument names
    private static final String ARG_COLUMN_COUNT = "column-count";
    // TODO: Customize parameters
    private int mColumnCount = 1;
    private ArrayList<ListComponent> components;

    /**
     * Mandatory empty constructor for the fragment manager to instantiate the
     * fragment (e.g. upon screen orientation changes).
     */
    public ComponentListFragment() {
    }

    public ComponentListFragment(ArrayList<ListComponent> components) {
        this.components = components;
    }

    // TODO: Customize parameter initialization
    @SuppressWarnings("unused")
    public static ComponentListFragment newInstance(int columnCount) {
        ComponentListFragment fragment = new ComponentListFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_COLUMN_COUNT, columnCount);
        fragment.setArguments(args);
        return fragment;
    }

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

        if (getArguments() != null) {
            mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_component_list_list, container, false);
        // Set the adapter
        if (view instanceof RecyclerView) {
            Context context = view.getContext();
            LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
            RecyclerView recyclerView = (RecyclerView) view;
            recyclerView.setHasFixedSize(true);
            recyclerView.addItemDecoration(
                    new DividerItemDecoration(recyclerView.getContext(),
                    linearLayoutManager.getOrientation())
            );
            if (mColumnCount <= 1) {
                recyclerView.setLayoutManager(linearLayoutManager);
            } else {
                recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
            }
            recyclerView.setAdapter(new MyItemRecyclerViewAdapter(components));
        }
        return view;
    }
}

Which builds a RecyclerView and sets the adapter to MyItemRecyclerViewAdapter.java:

package com.example.mclean_ross_s2030507;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

import com.example.mclean_ross_s2030507.databinding.FragmentComponentListBinding;
import com.example.mclean_ross_s2030507.placeholder.PlaceholderContent.PlaceholderItem;

import java.util.ArrayList;

/**
 * {@link RecyclerView.Adapter} that can display a {@link PlaceholderItem}.
 * TODO: Replace the implementation with code for your data type.
 */
public class MyItemRecyclerViewAdapter extends RecyclerView.Adapter<MyItemRecyclerViewAdapter.ViewHolder> {

    private final ArrayList<ListComponent> mValues;

    public MyItemRecyclerViewAdapter(ArrayList<ListComponent> items) {
        mValues = items;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new ViewHolder(FragmentComponentListBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        Log.e("MyTag", String.valueOf(holder));
        holder.mItem = mValues.get(position);
//        holder.mIdView.setText(mValues.get(position).id);
        holder.mContentView.setText(mValues.get(position).getTitle());

        holder.itemView.setOnClickListener(view -> {

        });
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder {
//        public final TextView mIdView;
        public final TextView mContentView;
        public ListComponent mItem;

        public ViewHolder(FragmentComponentListBinding binding) {
            super(binding.getRoot());
//            mIdView = binding.itemNumber;
            mContentView = binding.content;
        }

        @Override
        public String toString() {
            return super.toString() + " '" + mContentView.getText() + "'";
        }
    }
}

Finally, this is the view (fragment_component_list_list.xml) I am trying to achieve, but which is causing the error:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/edittext"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <androidx.recyclerview.widget.RecyclerView
        tools:viewBindingType="androidx.recyclerview.widget.RecyclerView"
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/list"
        android:name="com.example.mclean_ross_s2030507.ComponentListFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="0dp"
        android:layout_marginRight="0dp"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        tools:context=".ComponentListFragment"
        tools:listitem="@layout/fragment_component_list"
        android:scrollbars="vertical"/>

</LinearLayout>

However, the same file with the following setup works just fine:

<androidx.recyclerview.widget.RecyclerView
    tools:viewBindingType="androidx.recyclerview.widget.RecyclerView"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/list"
    android:name="com.example.mclean_ross_s2030507.ComponentListFragment"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="0dp"
    android:layout_marginRight="0dp"
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
    tools:context=".ComponentListFragment"
    tools:listitem="@layout/fragment_component_list"
    android:scrollbars="vertical"/>

Nested: Picture of RecycleView getting and display data

Not nested: Picture of RecycleView not getting data

I'm aware that various solutions to this error are all over SO, but I'm yet to see any specifically answering my issue regarding the nesting of RecyclerView. As always, any help is much appreciated. Cheers.



Solution 1:[1]

The view being inflated in onCreateView of ComponentListFragment is not a RecyclerView but a LinearLayout, based on the contents of R.layout.fragment_component_list_list you provided. The parent View/ViewGroup is always returned from inflate. So you need to reference the actual RecyclerView inside of that layout:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_component_list_list, container, false);
        RecyclerView rv = (RecyclerView) view.findViewById(R.id.list)
        // No need for if statement, just use `rv` variable...
        ...

Also, your XML has a few mistakes and areas for improvement:

  • Remove the redundant namespace (xmlns) attributes in the RecyclerView element and move xmlns:app to the root element.
  • The android:name attribute is only used in the <application> element of the AndroidManifest.xml
  • You don't need the tools:viewBindingType attribute. It's only needed to disambiguate generated views when using View Binding Type
  • tools:context is only meant for the root view. See tools attributes
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/edittext"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="0dp"
        android:layout_marginRight="0dp"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        tools:listitem="@layout/fragment_component_list"
        android:scrollbars="vertical"/>

</LinearLayout>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 zen_of_kermit