onCreateViewHolder of RecyclerView.Adapter is called twice or more, multiple times

It's not abnormal but quite normal behavior. You don't have to worry.

It is true that a ViewHolder will be recycled and won't be re-created again.

However, multiple ViewHolders are needed to display multiple items on the app's screen. So there will a certain numbers of ViewHolders are created and for that onCreateViewHolder is called a certain times.

And onBindViewHolder will be called infinitly whenever data is reset to one of ViewHolders.

I examined this fact with test application like below:

MainActivity:

public class MainActivity extends AppCompatActivity {
    private static final String[] DATASET = new String[]{
            "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
            "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        recyclerView.setHasFixedSize(true);

        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);

        MyAdapter myAdapter = new MyAdapter(DATASET);
        recyclerView.setAdapter(myAdapter);
    }
}

MyAdapter:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private static final String LOG_TAG = "RecyclerViewAdapter";
    private String[] dataset;

    private int counterOnCreateViewHolder = 0;
    private int counterOnBindViewHolder = 0;

    public MyAdapter(String[] dataset) {
        Log.d(LOG_TAG, "Construct");
        this.dataset = dataset;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public TextView textView;
        public ViewHolder(TextView textView) {
            super(textView);
            this.textView = textView;
        }
    }

    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Log.d(LOG_TAG, "onCreateViewHolder (" + ++counterOnCreateViewHolder + ")");
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.adapter_textview, parent, false);

        ViewHolder viewHolder = new ViewHolder((TextView) view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Log.d(LOG_TAG, "onBindViewHolder (" + ++counterOnBindViewHolder + ")");
        holder.textView.setText(dataset[position]);
    }

    @Override
    public int getItemCount() {
        // Log.d(LOG_TAG, "getItemCount");
        return dataset.length;
    }
}

layout/activity_main.xml:

<android.support.v7.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical"
    android:id="@+id/recycler_view" />

layout/adapter_textview.xml:

<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/adapter_textview"
    android:textSize="30sp" />

Result:

09-22 06:03:04.166 D/RecyclerViewAdapter﹕ Construct
09-22 06:03:05.179 D/RecyclerViewAdapter﹕ onCreateViewHolder (1)
09-22 06:03:05.183 D/RecyclerViewAdapter﹕ onBindViewHolder (1)
09-22 06:03:05.190 D/RecyclerViewAdapter﹕ onCreateViewHolder (2)
09-22 06:03:05.192 D/RecyclerViewAdapter﹕ onBindViewHolder (2)
09-22 06:03:05.192 D/RecyclerViewAdapter﹕ onCreateViewHolder (3)
09-22 06:03:05.194 D/RecyclerViewAdapter﹕ onBindViewHolder (3)
09-22 06:03:05.195 D/RecyclerViewAdapter﹕ onCreateViewHolder (4)
09-22 06:03:05.197 D/RecyclerViewAdapter﹕ onBindViewHolder (4)
09-22 06:03:05.198 D/RecyclerViewAdapter﹕ onCreateViewHolder (5)
09-22 06:03:05.199 D/RecyclerViewAdapter﹕ onBindViewHolder (5)
09-22 06:03:05.200 D/RecyclerViewAdapter﹕ onCreateViewHolder (6)
09-22 06:03:05.202 D/RecyclerViewAdapter﹕ onBindViewHolder (6)
09-22 06:03:05.203 D/RecyclerViewAdapter﹕ onCreateViewHolder (7)
09-22 06:03:05.204 D/RecyclerViewAdapter﹕ onBindViewHolder (7)
09-22 06:03:05.206 D/RecyclerViewAdapter﹕ onCreateViewHolder (8)
09-22 06:03:05.207 D/RecyclerViewAdapter﹕ onBindViewHolder (8)
09-22 06:03:05.209 D/RecyclerViewAdapter﹕ onCreateViewHolder (9)
09-22 06:03:05.211 D/RecyclerViewAdapter﹕ onBindViewHolder (9)
09-22 06:03:05.212 D/RecyclerViewAdapter﹕ onCreateViewHolder (10)
09-22 06:03:05.213 D/RecyclerViewAdapter﹕ onBindViewHolder (10)
09-22 06:03:05.215 D/RecyclerViewAdapter﹕ onCreateViewHolder (11)
09-22 06:03:05.217 D/RecyclerViewAdapter﹕ onBindViewHolder (11)
09-22 06:03:05.218 D/RecyclerViewAdapter﹕ onCreateViewHolder (12)
09-22 06:03:05.220 D/RecyclerViewAdapter﹕ onBindViewHolder (12)
09-22 06:03:55.048 D/RecyclerViewAdapter﹕ onCreateViewHolder (13)
09-22 06:03:55.050 D/RecyclerViewAdapter﹕ onBindViewHolder (13)
09-22 06:03:55.228 D/RecyclerViewAdapter﹕ onCreateViewHolder (14)
09-22 06:03:55.229 D/RecyclerViewAdapter﹕ onBindViewHolder (14)
09-22 06:03:55.230 D/RecyclerViewAdapter﹕ onCreateViewHolder (15)
09-22 06:03:55.231 D/RecyclerViewAdapter﹕ onBindViewHolder (15)
09-22 06:03:55.232 D/RecyclerViewAdapter﹕ onBindViewHolder (16)
09-22 06:03:55.232 D/RecyclerViewAdapter﹕ onBindViewHolder (17)
09-22 06:03:55.260 D/RecyclerViewAdapter﹕ onBindViewHolder (18)
09-22 06:03:55.276 D/RecyclerViewAdapter﹕ onBindViewHolder (19)
09-22 06:03:55.296 D/RecyclerViewAdapter﹕ onBindViewHolder (20)
09-22 06:03:55.310 D/RecyclerViewAdapter﹕ onBindViewHolder (21)

As you can see, only onBindViewHolder was called after onCreateViewHolder (15).


Here is a stable answer to stable Views for RecyclerView

These below line help to consistent list data in recyclerview vertically In my vertical list having only 10 items which i don't want to rebind again. Each row having infinite horizontal RecyclerView list.

  1. mRecyclerview.getRecycledViewPool().setMaxRecycledViews(int viewtype,int itemsCount)

  2. mRecyclerview.setItemViewCacheSize(int itemsCount)

    Both method helps not to recycle vertical views. But if list is too large then it will cause you OOM error, So be carefull to implement it.

    Here 0 is viewType in Recyclerview adapter and 10 are the items count.
    
    mRecyclerview.getRecycledViewPool().setMaxRecycledViews(0, 10);
    mRecyclerview.setItemViewCacheSize(10);
    

You can increase the RecycledViewPool count by this code. By default it have 5.

you can increase as per your need.

recyclerView.getRecycledViewPool().setMaxRecycledViews(0,50);//0 - your view type