[android] recyclerview No adapter attached; skipping layout



Answers

I was getting the same two error messages until I fixed two things in my code:

(1) By default, when you implement methods in the RecyclerView.Adapter it generates:

 @Override
    public int getItemCount() {
        return 0;
    }

Make sure you update your code so it says:

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

Obviously if you have zero items in your items then you will get zero things displayed on the screen.

(2) I was not doing this as shown in the top answer: CardView layout_width="match_parent" does not match parent RecyclerView width

//correct
LayoutInflater.from(parent.getContext())
            .inflate(R.layout.card_listitem, parent, false);

//incorrect (what I had)
LayoutInflater.from(parent.getContext())
        .inflate(R.layout.card_listitem,null);

(3) EDIT: BONUS: Also make sure you set up your RecyclerView like this:

            <android.support.v7.widget.RecyclerView
            android:id="@+id/RecyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />

NOT like this:

            <view
            class="android.support.v7.widget.RecyclerView"
            android:id="@+id/RecyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            />

I have seen some tutorials using the latter method. While it works I think it generates this error too.

Question

Just implemented Recyclerview in my code, replacing Listview.

everything works fine. The objects are displayed.

but logcat says

15:25:53.476 E/RecyclerView﹕ No adapter attached; skipping layout

15:25:53.655 E/RecyclerView﹕ No adapter attached; skipping layout

for the code

ArtistArrayAdapter adapter = new ArtistArrayAdapter(this, artists);
recyclerView = (RecyclerView) findViewById(R.id.cardList);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));

As you can see I have attached an adapter for Recycleview. so why do I keep getting this error?

i have read other questions related to same problem but none helps.




I have solved this error. You just need to add layout manager and add the empty adapter.

Like this code:

myRecyclerView.setLayoutManager(...//your layout manager);
        myRecyclerView.setAdapter(new RecyclerView.Adapter() {
            @Override
            public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                return null;
            }

            @Override
            public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

            }

            @Override
            public int getItemCount() {
                return 0;
            }
        });
//other code's 
// and for change you can use if(mrecyclerview.getadapter != speacialadapter){
//replice your adapter
//}



My problem was my recycler view looked like this

        <android.support.v7.widget.RecyclerView
        android:id="@+id/chatview"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent">
    </android.support.v7.widget.RecyclerView>

When it should have looked like this

       <android.support.v7.widget.RecyclerView
        android:id="@+id/chatview"
        android:layout_width="395dp"
        android:layout_height="525dp"
        android:layout_marginTop="52dp"
        app:layout_constraintTop_toTopOf="parent"
        tools:layout_editor_absoluteX="8dp"></android.support.v7.widget.RecyclerView>
</android.support.constraint.ConstraintLayout>



i have this problem , a few time problem is recycleView put in ScrollView object

After checking implementation, the reason appears to be the following. If RecyclerView gets put into a ScrollView, then during measure step its height is unspecified (because ScrollView allows any height) and, as a result, gets equal to minimum height (as per implementation) which is apparently zero.

You have couple of options for fixing this:

  1. Set a certain height to RecyclerView
  2. Set ScrollView.fillViewport to true
  3. Or keep RecyclerView outside of ScrollView. In my opinion, this is the best option by far. If RecyclerView height is not limited - which is the case when it's put into ScrollView - then all Adapter's views have enough place vertically and get created all at once. There is no view recycling anymore which kinda breaks the purpose of RecyclerView .

(Can be followed for android.support.v4.widget.NestedScrollView as well)




Solved by setting the initialized empty list and adapter at the bottom and calling notifyDataSetChanged when results are fetched.

    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
    recyclerviewItems.setLayoutManager(linearLayoutManager);
    someAdapter = new SomeAdapter(getContext(),feedList);
    recyclerviewItems.setAdapter(someAdapter);



I had the same problem and realized I was setting both the LayoutManager and adapter after retrieving the data from my source instead of setting the two in the onCreate method.

salesAdapter = new SalesAdapter(this,ordersList);
        salesView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
        salesView.setAdapter(salesAdapter);

Then notified the adapter on data change

               //get the Orders
                Orders orders;
                JSONArray ordersArray = jObj.getJSONArray("orders");
                    for (int i = 0; i < ordersArray.length() ; i++) {
                        JSONObject orderItem = ordersArray.getJSONObject(i);
                        //populate the Order model

                        orders = new Orders(
                                orderItem.getString("order_id"),
                                orderItem.getString("customer"),
                                orderItem.getString("date_added"),
                                orderItem.getString("total"));
                        ordersList.add(i,orders);
                        salesAdapter.notifyDataSetChanged();
                    }



It happens when you are not setting the adapter during the creation phase:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
    ....
}

public void onResume() {
    super.onResume();
    mRecyclerView.setAdapter(mAdapter);
    ....
}

Just move setting the adapter into onCreate with an empty data and when you have the data call:

mAdapter.notifyDataSetChanged();



ArtistArrayAdapter adapter = new ArtistArrayAdapter(this, artists);
recyclerView = (RecyclerView) findViewById(R.id.cardList);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);

Just replace above code with this and it should work. What you did wrong is you called setAdapter(adapter) before calling layout manager.




For those who use the recycler view within a fragment and inflate it from other views: when inflating the whole fragment view, make sure that you bind the recycler view to its root view.

I was connecting and doing everything for the adapter correctly, but I never did the binding. This answer by @Prateek Agarwal has it all for me, but here is more elaboration.

Kotlin

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {

    val rootView =  inflater?.inflate(R.layout.fragment_layout, container, false)
    recyclerView = rootView?.findViewById(R.id.recycler_view_id)
    // rest of my stuff
    recyclerView?.setHasFixedSize(true)
    recyclerView?.layoutManager = viewManager
    recyclerView?.adapter = viewAdapter
    // return the root view
    return rootView
}

Jave

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

    View rootView= inflater.inflate(R.layout.fragment_layout,container.false);
    recyclerview= rootView.findViewById(R.id.recycler_view_id);
    // rest ...
    return rootView;
}



These Lines must be in OnCreate:

mmAdapter = new Adapter(msgList);
mrecyclerView.setAdapter(mmAdapter);



I had the same error I fixed it doing this if you are waiting for data like me using retrofit or something like that

Put before Oncreate

private ArtistArrayAdapter adapter;
private RecyclerView recyclerView;

Put them in your Oncreate

 recyclerView = (RecyclerView) findViewById(R.id.cardList);
 recyclerView.setHasFixedSize(true);
 recyclerView.setLayoutManager(new LinearLayoutManager(this));
 adapter = new ArtistArrayAdapter( artists , R.layout.list_item ,getApplicationContext());
 recyclerView.setAdapter(adapter);

When you receive data put

adapter = new ArtistArrayAdapter( artists , R.layout.list_item ,getApplicationContext());
recyclerView.setAdapter(adapter);

Now go in your ArtistArrayAdapter class and do this what it will do is if your array is empty or is null it will make GetItemCount return 0 if not it will make it the size of artists array

@Override
public int getItemCount() {

    int a ;

    if(artists != null && !artists.isEmpty()) {

        a = artists.size();
    }
    else {

        a = 0;

     }

   return a;
}



Links