2

I keep getting the error "RecyclerView: No adapter attached; skipping layout" when the RecyclerView list is shown. I have 3 tabs and one tab has a RecyclerView list that is populated from SQLite database. I don't get any crashes and the data is shown correctly in the view but I still get this error.

I thought it was just a warning because the data is in place correctly but when I tried onClick it doesn't work and I'm sure it has something to do with this error.

I know this question has been asked a lot before but I checked most of the questions and none has worked for me.

This is my fragment:

public class RecentsFragment extends Fragment {
    DatabaseHelper helper;
    List<MyPojo> dbList;
    RecyclerView mRecyclerView;
    private MyGridAdapter mAdapter;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        final View view = inflater.inflate(R.layout.my_recents_list, container, false);
        mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
        mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2));
        mRecyclerView.setHasFixedSize(true);
        return view;
    }
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        setHasOptionsMenu(true);
        dbList = new ArrayList<MyPojo>();

        dbList = getCat(); // getCat returns array list from sqlite database

        mAdapter = new MyGridAdapter(dbList);
        mRecyclerView.setAdapter(mAdapter);

    }
}

My adapter:

public class MyGridAdapter extends RecyclerView.Adapter<MyGridAdapter.ViewHolder> {

    static List<MyPojo> dbList;
    static Context context;

    MyGridAdapter(Context context, List<MyPojo> dbList){
        this.dbList = new ArrayList<MyPojo>();
        this.context = context;
        this.dbList = dbList;

    }


    MyGridAdapter(List<MyPojo> dbList){
        this.dbList = new ArrayList<MyPojo>();
        this.dbList = dbList;

    }

    @Override
    public MyGridAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(
                R.layout.categories_item, null);

        ViewHolder viewHolder = new ViewHolder(itemLayoutView);
        return viewHolder;
    }

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

        holder.title.setText(dbList.get(position).getCat());
    }

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

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        public TextView title;
        public LinearLayout placeHolder;
        ImageView image;

        public ViewHolder(View itemLayoutView) {
            super(itemLayoutView);
            title = (TextView) itemLayoutView.findViewById(R.id.placeName);

        }

        @Override
        public void onClick(View v) {
            Intent intent = new Intent(context, DetailsActivity.class);

            Bundle extras = new Bundle();
            extras.putInt("catid", dbList.get(getAdapterPosition()).getCatid());
            intent.putExtras(extras);

            context.startActivity(intent);

        }
    }
}

Thanks in advance

Update: my_recents_list.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".RecentsFragment">


    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#f8f8f8"
        android:divider="@null"
        android:listSelector="@android:color/transparent"/>

</LinearLayout>
u_kami
  • 565
  • 12
  • 28

1 Answers1

3

To avoid this error, avoid to do the findViewById into the CreateView method but instead do it into the onViewCreated.

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

    return inflater.inflate(R.layout.my_recents_list, container, false);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
    mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2));
    mRecyclerView.setHasFixedSize(true);

    setHasOptionsMenu(true);
    dbList = new ArrayList<MyPojo>();

    dbList = getCat(); // getCat returns array list from sqlite database

    mAdapter = new MyGridAdapter(getActivity(), dbList);
    mRecyclerView.setAdapter(mAdapter);

}

Edit

You Adapter should be like:

public class MyGridAdapter extends RecyclerView.Adapter<MyGridAdapter.ViewHolder> {

    private List<MyPojo> dbList;
    private Context context;

    MyGridAdapter(Context context, List<MyPojo> dbList) {
        this.dbList = new ArrayList<MyPojo>(dbList);
        this.context = context;
    }

    @Override
    public MyGridAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // Note that the inflate method takes the layout to inflate, the parent to measure 
        // the layout and the third parameters is false so only this view will handle events like click event
        View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.categories_item, parent, false);

        return new ViewHolder(itemLayoutView);
    }

    @Override
    public void onBindViewHolder(final MyGridAdapter.ViewHolder holder, final int position) {
        MyPojo myPojo = dbList.get(position);
        holder.title.setText(myPojo.getCat());
        //You can register the click listener to the textview (or the whole item if you put it into the holder)
        holder.title.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(context, DetailsActivity.class);

            Bundle extras = new Bundle();
            extras.putInt("catid", dbList.get(position).getCatid());
            intent.putExtras(extras);

            context.startActivity(intent);
            }
        });
    }

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

    //The class is static to avoid leaks from a non-static nested class
    public static class ViewHolder extends RecyclerView.ViewHolder {

        public TextView title;

        public ViewHolder(View itemLayoutView) {
            super(itemLayoutView);
            title = (TextView) itemLayoutView.findViewById(R.id.placeName);

        }
    }
}
xiaomi
  • 6,553
  • 3
  • 29
  • 34
  • I also wanted to point out your ViewHolder. It should be a `public static class` (because a non static nested class keep a reference to the adapter and it can produce leaks). – xiaomi Feb 24 '16 at 02:23
  • thanks but I followed more than one tutorial and most use public class..what about my main problem what do you think is the main cause? – u_kami Feb 24 '16 at 16:17
  • I copy-pasted your code but I can't reproduce your problem. Can you put your my_recents_lists xml ? By the way, inside your adapter `static List dbList` and `static Context context` should not be `static` – xiaomi Feb 24 '16 at 16:50
  • thanks a lot for pointing it out! I have updated my question with the xml code. – u_kami Feb 24 '16 at 17:04
  • I tested but I still wasn't able to reproduce the problem. Did you try to run your code on both phone and emulator ? – xiaomi Feb 25 '16 at 01:46
  • I am testing on my phone. Did you try clicking on one of the items and it worked? the onClick is not being called because there is no adapter attached..I don't know why this is happening. In my app I ave 3 tabs and this is the second tab, also please note that everything is showing correctly no crashes just the onClick is not working and I am getting this error in the logcat. Did you use exactly the same code? Can you show me what you did?..Thanks for your time :) – u_kami Feb 25 '16 at 11:45
  • If you click on an item, nothing will occurred because you didn't set the setOnClickListener of the view. I edit my answer with an example. I also change the new MyGridAdapter to put the context for your intent. If you still have a problem after that, I will directly give you a working example that you can use. – xiaomi Feb 25 '16 at 13:06
  • Thanks a lot!! I tried your code it worked but without the tabs..when I add the fragment in the tab it gives me the same error..it looks like I need to sort out the tabs code. – u_kami Feb 25 '16 at 14:35