72

Not getting any errors and all the data seems valid. For some reason, nether of the view related methods are being called. I have made sure of the following:

  • getItemCount() is the only adapter method being called and is returning a positive integer value, (I know this will be the area you guys will look at)

    • Constructor is being called, member variables are valid.

    • Parent View is a vertical LinearLayout; no scrollview, or any other view with their own scroll properties in sight.

    • containing fragment view is created and shown on screen.

Here is the declaration in the fragment followed by the adapter. Any help would be appreciated as this has be completely baffled.

SubMenuAdapter adapter = new SubMenuAdapter(getActivity(), mContentItems);
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setAdapter(adapter);
public class SubMenuAdapter extends RecyclerView.Adapter<SubMenuAdapter.ViewHolder> {
private static final String TAG = String.format("==> %S", SubMenuAdapter.class.getSimpleName());

private final List<ContentItem> mContentItems;
private Context mContext;

public SubMenuAdapter(Context context, List<ContentItem> contenItems) {
    Log.d(TAG, "Constructor called");
    mContentItems = contenItems;
    mContext = context;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    Log.d(TAG, "onCreateViewHolder called");
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_resource_efficiency, parent, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    Log.d(TAG, "onBindViewHolder called");

    ContentItem item = mContentItems.get(position);
    holder.textName.setText(item.getName());
    FontSetter.setMyriadProRegular(mContext, holder.textName);
    Picasso.with(mContext).load("file://" + item.getPreviewImageDefault()).into(holder.imageIcon);
}

@Override
public int getItemCount() {
    Log.d(mContext, String.format("getItemCount: %d", mContentItems.size()));
    return mContentItems.size();
}

// ViewHolder
public static class ViewHolder extends RecyclerView.ViewHolder {

    TextView textName;
    ImageView imageIcon;

    public ViewHolder(View view) {
        super(view);
        textName = (TextView) view.findViewById(R.id.tv_resource_efficiency_option);
        imageIcon = (ImageView) view.findViewById(R.id.iv_resource_efficiency_icon);
    }
}
florianmski
  • 5,603
  • 1
  • 17
  • 14
Conti
  • 1,017
  • 1
  • 11
  • 15
  • Are you sure your recyclerview visibility is set to visible ? Does your recyclerview has a decent height (try to put a background to your recyclerview so you can see visually if it takes any sapce at all in your layout) ? – florianmski Mar 11 '15 at 23:02
  • 2
    I tried 'match_parent', 'wrap_content' and a size of 400dp, all with a blue background value and still nothing. I also explicitly set the visibility to visible -- still nothing. Although I wasn't expecting it to appear anyway as the methods weren't called to create and bind the views. – Conti Mar 12 '15 at 07:33
  • That's super weird, I use recyclerview exactly like this minus setting the DefaultAnimator as it's already done by default... – florianmski Mar 12 '15 at 13:39
  • 1
    I have the same problem, data in adapter changed, notifyDataSetChanged called, setAdapter executed, fragment alive and drawed, but onCreateViewHolder or onBindView didn't call. All veiws visible. – Raskilas Apr 08 '15 at 22:56
  • I just gave up and went back to using a CursorAdapter with ListView. I wasted way too many hours on it. – Conti Apr 09 '15 at 13:41
  • 1
    I have the same problem my Adapter method getItemCount() return greater then 0 and still does not have positive result. I think there has a problems with SrollView and RecycleView working toghether. – Stoycho Andreev Apr 26 '15 at 13:16
  • 1
    This is also happening to me. Weird thing is I have another RecyclerView in the same project that is working perfectly. – Martin Epsz Aug 04 '15 at 19:08
  • @Conti Let's see your layout where you defined the RecyclerView. As answered by radityagumay below, your issue may be nesting the RecyclerView in a ScrollView - which would cause it to be hidden. – IgorGanapolsky Oct 15 '15 at 12:41
  • 2
    @IgorGanapolsky I'll have to search through my BitBucket and find it, I submitted this question 7 months ago and gave up after spending hours on it. But check my 3rd bullet point, _"Parent View is a vertical LinearLayout; no scrollview, or any other view with their own scroll properties in sight."_ There were no scrollviews in the hierarchy at all. – Conti Oct 16 '15 at 08:55
  • 1
    @Conti you managed to solve this problem?? – Raghunandan Feb 12 '16 at 13:10
  • Possible duplicate of [Recyclerview not call onCreateViewHolder](http://stackoverflow.com/questions/27809524/recyclerview-not-call-oncreateviewholder) – J Wang Sep 28 '16 at 18:59
  • Make sure that the `RecyclerView` is not a `ConstraintLayout` child – David Luque Oct 12 '17 at 10:56
  • add setLayoutManager() – AMIT Mar 07 '18 at 10:50
  • @DavidLuque you are awesome. – Bineesh P Babu Oct 28 '18 at 04:45

24 Answers24

109

This may also help someone

First Use

recyclerView.setAdapter(adapter);

And then:

recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

So it will look like this:

recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

The order is reversed

Update:

Nowadays I simply use:

app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"

on the RecyclerView in the xml

Aerim
  • 1,960
  • 3
  • 16
  • 28
  • 3
    do you have any link to an explanation why this has to be this way? – igoris Sep 08 '16 at 20:14
  • Hi @igoris sadly I do not, I only got to this solution by trial and error. – Aerim Sep 09 '16 at 17:26
  • 9
    LayoutManager is one of the most annoying bugs that I've made millions of times and I always forgot about it. I'm going to print and frame on the wall: "Setup the Layout Manager!" :) – daneejela Feb 05 '19 at 22:27
  • I would think that if you set the `LayoutManager` before the adapter it will already have measured something and it doesn't think it needs to do it again. This is just theory nothing proved – Aerim Apr 29 '19 at 15:02
  • 1
    Genius! But it was combination of your answer + removing @VenakteshShukla's answer – who-aditya-nawandar Aug 04 '21 at 07:59
49

Been chasing answer for over an hour.

Dont forget to call this one liner before setting your adapter.

recyclerView.setLayoutManager(new LinearLayoutManager(this));

It seems that recycler view do not have default layout manager option built in so we have to programatically add it.

Cheers if you found it helpful.

ralphgabb
  • 10,298
  • 3
  • 47
  • 56
19

Make sure you recycle view is not child from nestedscrollview

for example, this code will not work.

<android.support.v4.widget.NestedScrollView
    android:id="@+id/responder_scroll"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/darkGray"
    android:clipToPadding="false"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            app:cardElevation="@dimen/spacing_medium"
            app:cardUseCompatPadding="true">

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:id="@+id/responder_testimonial"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentTop="true"
                    android:text="Testimonial"
                    android:textSize="@dimen/general_font_size" />

                <TextView
                    android:id="@+id/responder_counter_testimonial"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_toRightOf="@+id/responder_testimonial"
                    android:text="170"
                    android:textSize="@dimen/general_font_size_small" />

                <Button
                    android:id="@+id/responder_btn_testimonial"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:layout_alignParentTop="true"
                    android:text="Go" />

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

    </FrameLayout>
</android.support.v4.widget.NestedScrollView>

then i use,

<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">

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

raditya gumay
  • 2,951
  • 3
  • 17
  • 24
11

I don't know if this will be helpful to anyone, but I almost had the same exact problem. My problem was not in either the fragment/class nor the recycler adapter. The problem was in parent XML layout where the actionbar took match_parent where the FrameLayout -in which the fragment is replaced- didn't get any available place to be shown. That's why the methods weren't called.

I guess similar scenarios might be the case for those facing the same problem. Double check every width and height in every XML file might be in the same tree, as the problem doesn't seem to be in the adapter at all.

11

My two pennies here. Just spent more than three hours debugging this.

Make sure that you have not used the following line carelessly.

recyclerView.setHasFixedSize(true);

Set the fixed size only when you are sure that the view would have a constant size. In case it is not, the onCreateViewHolder and onBindView methods might not get called at all.

  • 1
    Thanks a lot. This worked for me. Also, mentioned the same answer [here](http://stackoverflow.com/questions/27809524/recyclerview-not-call-oncreateviewholder/42054411#42054411) – venky Feb 05 '17 at 16:29
  • 1
    I've been looking for everywhere. And the problem was exactly that! – Gabriel Aug 04 '17 at 17:11
8

I had also face the same issue where onCreateViewHolder or onBindView method was not getting invoke, only getItemCount was getting invoked. So it was basically issue with the height and weight of RecyclerView which was set to wrap_content or 0dp. After changing it to some value fixed the problem.

stefanobaghino
  • 11,253
  • 4
  • 35
  • 63
Vijay Pal
  • 181
  • 1
  • 2
  • 5
4

This is really old already, but in my case, I was using a ConstraintLayout and the height was set wrong so my view would have 0dp and then the adapter would be saving to do its job, as the view is 0dp.

Make sure height and width is ok and RecyclerView is has a positive size.

Rafael Ruiz Muñoz
  • 5,333
  • 6
  • 46
  • 92
3

In my case after changing Activity to ViewModel and using Binding, I had forgotten to remove setContentView from onCreate method. By removing it my problem solved.

Siamak Ferdos
  • 3,181
  • 5
  • 29
  • 56
2

If you put wrap_content as height of your list as well as the height of your item list, nothing will show up and none of your recyclerView functions will be called.

Meriam
  • 945
  • 8
  • 18
2

When implementing FirebaseListAdapter , one need to take care of following points to set it up correctly.

  1. Check if recyclerview in xml has all attributes correct. Don't use wrap content for height & width, for instance.
  2. Please check if layoutManager is set & setHasFixedSize() is taken care of.
  3. Make POJO class variables so that they match firebase child attributes.
  4. FirebaseRecyclerOptions is set up.
  5. FirebaseRecyclerAdapter's onCreateViewHolder() & onBindViewHolder are there.
  6. Lifecycle events are taken care of.

Note- Using wrap_content as height of recyclerview is one of easiest mistake anyone can do. So do check that first.

1

I know this topic is old, but if you did the same learner mistake, as I did, you might find this helpful.

As I was studying on some website about RecyclerView and copying some code and adapting to my context, I have created different variables (eg users and data) which were meant to do the same thing, except some methods were calling data and some were calling users. This is an easy mistake to do as you try to understand other's code and java functionality (it happens to me all the time).

It's good to know that you can println in your console anywhere in your java code, so you can debug like that pretty easily.

Good luck!

bem22
  • 276
  • 1
  • 14
1

In my case it was using setHasStableIds(true); in the adapter while some list items were returning -1 in getItemID(), so I suppose the RecyclerView was thinking they are equal.

David
  • 3,971
  • 1
  • 26
  • 65
  • Thanks! Wasted many hours on it. `onBindViewHolder` sometimes didn't call. In my case I wrongly added setHasStableIds(true); in adapter's constructor. – CoolMind Apr 28 '18 at 14:41
1

In my case a had a Fragment with RecyclerView inside a ViewPager. The issue appeared because i used Fragment.getFragmentManager() instead of Fragment.getChildFragmentManager for my FragmentStatePagerAdapter's constructor.

P.S. Using Layout Inspector might be a great help at debugging this sort of issue.

Daniil
  • 1,290
  • 11
  • 17
1

Be careful about the thread you are working with adapter.
In my case the problem was calling notifyDataSetChanged() from an activity when my data came from a service. Actually the method was calling from background thread. But the app didn't crash and there was nothing in Logcat (!).
So i was called notifyDataSetChanged() in UI thread and the problem solved.

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        adapter.notifyDataSetChanged();
    }
});
Seyyed
  • 1,526
  • 3
  • 20
  • 30
1

In my case I was setting recycler view adapter as recyclerview.apply { adapter = adapter }

both referring to the getAdapter() so renamed my adapter variable name as folderAdapter

1

Sometimes this bug occurs if you put viewpager inside a scrollview which will shrink the parent view along with the viewpager and its child fragments. Therefore with now view to be found for child fragments onCreateView and onBindView methods will not be called. Simply remove scrollview or add weights to your layout so that the views don't shrink.

VIVek
  • 121
  • 1
  • 4
0

I had this same issue where neither onCreateViewHolder or onBindViewHolder were being called. Changing your onCreateViewHolder method to use the Context you saved a reference to in the constructor instead of doing parent.getContext() should fix it:

public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    Log.d(TAG, "onCreateViewHolder called");
    View view = LayoutInflater.from(mContext).inflate(R.layout.row_resource_efficiency, parent, false);
    return new ViewHolder(view);
dpspae03
  • 79
  • 1
  • 10
0

In my case I set the ID of my RecyclerView to "recyclerView". It seems that this ID was already defined somewhere, because when I changed that to different ID, the methods from the adapter were called properly.

Link to the answer

Community
  • 1
  • 1
0

I recently encountered this problem and apparently there are many possible causes. Try one or combination of these options, see which one(s) work(s) for you :)

1. Layout manager
Ensure that you set a layout manager to your recycler view as below

// create a layout manager
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(my_context);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);

// get recycler view
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_id);
// set
recyclerView.setLayoutManager(linearLayoutManager);

2. Fixed Size
Ensure that you state whether your recycler view has a fixed size or not

// set fixed size
recyclerView.setHasFixedSize(true); // or false depending on implementation

3. XML
Ensure that your recycler is not nested in too many layouts which may cause confusion such as combination of ScrollView and RelativeLayout. Make it simple, see if it fixes your issue

<?xml version="1.0" encoding="utf-8"?>
<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">

<android.support.v7.widget.RecyclerView
android:id="@+id/thread_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Jonathan Kibet
  • 621
  • 7
  • 12
0

if you are using constraint layout when you are set recyclerview height to match parent (0) this problem occur

Mil Farad
  • 1
  • 1
0

I have the following situation:

@Override
    protected void onStart() {
        super.onStart();
        Log.d("OnStart","Calling OnStart.");
        FirebaseRecyclerOptions<Data> options = new FirebaseRecyclerOptions.Builder<Data>().setQuery(mDatabase, new SnapshotParser<Data>() {
            @NonNull
            @Override
            public Data parseSnapshot(@NonNull DataSnapshot snapshot) {
                Log.d("parseSnapshot",snapshot.child("name").getValue().toString());
                return new Data(snapshot.child("name").getValue().toString(),
                        snapshot.child("description").getValue().toString(),
                        snapshot.child("id").getValue().toString(),
                        snapshot.child("date").getValue().toString());
            }
        }).build();
        FirebaseRecyclerAdapter<Data,MyViewHolder> adapter = new FirebaseRecyclerAdapter<Data, MyViewHolder>(options) {
            @Override
            protected void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i, @NonNull Data data) {
                Log.d("OnBindViewHolder",data.getName());
                myViewHolder.setName(data.getName());
                myViewHolder.setDescription(data.getDescription());
                myViewHolder.setDate(data.getDate());
            }

            @NonNull
            @Override
            public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                Log.d("OnCreateViewHolder","Creating the viewHolder");
                View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itemlayout,parent,false);
                return new MyViewHolder(view);
            }
        };
        recyclerView.setAdapter(adapter);
        Log.d("OnStart","Exiting OnStart.");
    }

and OnCreateViewHolder and OnBindViewHolder are not being called.

0

In my case I've been using paging library and PagingDataAdapter. I set an adapter AFTER all it's data were already fetched from a PagingSoure and RecyclerView didn't show anything. I solved this by calling adapter.refresh() just after setting the adapter. Like this:

recyclerView.adapter = myAdapter
myAdapter.refresh()
Sergey Stasishin
  • 291
  • 2
  • 10
0

I had the same problem. In my case recyclerView got empty after several refresh. For example when I clicked on a item and got back from another activity. I had data but data did not set to recyclerView and there was no error.

I created the recyclerView on onCreate method like this :

        StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
        binding.recyclerCommodityList2.setLayoutManager(staggeredGridLayoutManager);
        binding.recyclerCommodityList2.addItemDecoration(new GridSpacingItemDecoration(2, 0, true));
        adapterCommodityList = new RecyclerAdapterMyCommoditiAndPost(cardList.getCard(), context);
        binding.recyclerCommodityList2.setAdapter(adapterCommodityList);

        binding.recyclerCommodityList2.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NotNull RecyclerView recyclerView, int dx, int dy) {
                visibleItemCount = staggeredGridLayoutManager.getChildCount();
                totalItemCount = staggeredGridLayoutManager.getItemCount();

                if (dy > 0) { //check for scroll down

                    pastVisibleItems = staggeredGridLayoutManager.findFirstVisibleItemPositions(null)[1];

                    if ((visibleItemCount + pastVisibleItems) >= totalItemCount / 2 ) {

                        if (loading) {
                            loading = false;
                            callGetListOfCommodity(selectedCategory); // call api again
                        }
                    }

                }
            }
        });

and I sat data on api onResponse method like this :

adapterCommodityList = new RecyclerAdapterMyCommoditiAndPost(result.getCard(), MyTamukActivity.this);
binding.recyclerCommodityList2.setAdapter(adapterCommodityList);

So I sat a new layout manager on onResponse method. like this :

StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
binding.recyclerCommodityList2.setLayoutManager(staggeredGridLayoutManager);

adapterCommodityList = new RecyclerAdapterMyCommoditiAndPost(result.getCard(), MyTamukActivity.this);
binding.recyclerCommodityList2.setAdapter(adapterCommodityList);

This solution worked but still sometimes recyclerView got empty.

So this is my final solution :

I removed recyclerView from onCreate then I created the recyclerView on onResume method instead of that. So layout manager always sat on recyclerView correctly.

Any way if you have same problem check your layout manager and how you set that on recyclerView.

Ghazal
  • 123
  • 2
  • 9
0

If you put your recyclerview inside scrollview, replace scrollview with NestedScrollView and put this line inside recyclerview tag

            android:overScrollMode="never"
Hagar Magdy
  • 293
  • 2
  • 10