RecyclerView.Adapter的onCreateViewHolder被多次调用两次或多次

我目前正在开发一个使用RecyclerView的应用程序。

在审查LogCat时,我注意到onCreateViewHolder在实例化后被调用了两次。

09-22 05:22:55.209 V/Adapter﹕ Construct 09-22 05:22:55.213 V/Adapter﹕ onCreateViewHolder 09-22 05:22:55.224 V/Adapter﹕ onBindViewHolder 09-22 05:22:55.240 V/Adapter﹕ onCreateViewHolder 09-22 05:22:55.247 V/Adapter﹕ onBindViewHolder 

另外onBindViewHolder被调用了两次,但我知道它被称为每当项目被回收。

但我认为onCreateViewHolder是足够的被调用一次。

这是不正常的行为? 如果是这样,那该如何解决?

  • 即使RecyclerView.findViewHolderForAdapterPosition()在该位置返回null,onBindViewHolder()也不会在位置视图上调用
  • 应该持有人参考适配器?
  • RecyclerView.ViewHolder总是必须是一个内部类吗?
  • RecyclerView itemView OnGlobalLayoutListener不会触发所有itemViews
  • 什么导致这个exceptionjava.lang.RuntimeException:java.lang.NoSuchMethodException:<init>
  • Android:RecyclerView内容滚动后搞砸了
  • dynamic地将RecyclerView中的视图添加到当前项目
  • 什么更好? notifyDataSetChanged或notifyItemChanged循环?
  • 这不是反常的,而是很正常的行为。 你不必担心。

    确实,ViewHolder将被回收,不会再被重新创build。

    但是,需要多个ViewHolders才能在应用程序的屏幕上显示多个项目。 所以会有一定数量的ViewHolder被创build,并为此onCreateViewHolder被调用一定的时间。

    当数据重置为ViewHolders时,onBindViewHolder将被无限调用。

    我用下面的testing应用程序来检查这个事实:

    主要活动:

     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; } } 

    布局/ 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" /> 

    布局/ 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" /> 

    结果:

     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) 

    正如你所看到的,只有onBindViewHolder在onCreateViewHolder (15)之后被调用。