RecycledViewPool使用

Adapter最佳实践


使用RecycledViewPool来缓存item

Recycled view pools allow multiple RecyclerViews to share a common pool of scrap views. This can be useful if you have multiple RecyclerViews with adapters that use the same view types, for example if you have several data sets with the same kinds of item views displayed by a ViewPager.
RecyclerView automatically creates a pool for itself if you don’t provide one.

正如上文所说RecycledViewPool的主要作用是多个页面的item共享,比如是可以滑动的tab页面,每个页面的vh都是一样的,在这种情况下用它就很合适了。

image.png
image.png

斗鱼的个tab的页面里面的item都是完全一样的,对于首页这个多fragment的结构来说,采用viewpool会大大提性能。

Tips:

  • 因为commonAdapter帮助你将各种类型的type都转换为int知了,所以需要采用自定义的RecyclePool来做这样的操作。
RecycledViewPool pool = new RecycledViewPool();

// ...

recyclerView.setRecycledViewPool(pool);
adapter.setTypePool(pool.getTypePool());复制代码
  • RecycledViewPool是依据ItemViewType来索引ViewHolder的,所以不同页面的相同的item的type必须是一样的值才能被准确的复用。

  • RecycledViewPool也可以通过mPool.setMaxRecycledViews(itemViewType, number)来设置缓存数目。

  • RecyclerView可以通过recyclerView.setItemViewCacheSize(number)设置自己所需要的ViewHolder数量,只有超过这个数量的detached ViewHolder才会丢进ViewPool中与别的RecyclerView共享。也就说每个页面可以设置自己不想和别的页面共用的viewholder数目。

  • 在合适的时机,RecycledViewPool会自我清除掉所持有的ViewHolder对象引用,当然你也可以在你认为合适的时机手动调用clear()。


代码测试

ViewPager包含3个Fragment,每个Fragment中显示形式一样,启动应用后点击tab0和tab2进行切换,查看日志

不共用RecycledViewPool的情况下

09-26 14:16:08.003 24243-24243/? I/recycleviewdem: Not late-enabling -Xcheck:jni (already on)
09-26 14:16:08.035 24243-24243/? W/recycleviewdem: Unexpected CPU variant for X86 using defaults: x86
09-26 14:16:08.387 24243-24243/com.github.leon.recycleviewdemo W/recycleviewdem: JIT profile information will not be recorded: profile file does not exits.
09-26 14:16:08.389 24243-24243/com.github.leon.recycleviewdemo I/chatty: uid=10087(com.github.leon.recycleviewdemo) identical 10 lines
09-26 14:16:08.390 24243-24243/com.github.leon.recycleviewdemo W/recycleviewdem: JIT profile information will not be recorded: profile file does not exits.
09-26 14:16:08.473 24243-24243/com.github.leon.recycleviewdemo I/InstantRun: starting instant run server: is main process
09-26 14:16:08.965 24243-24254/com.github.leon.recycleviewdemo I/recycleviewdem: Background concurrent copying GC freed 39849(7MB) AllocSpace objects, 0(0B) LOS objects, 52% free, 1371KB/2MB, paused 2.622ms total 326.052ms
09-26 14:16:08.966 24243-24243/com.github.leon.recycleviewdemo W/recycleviewdem: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
09-26 14:16:08.967 24243-24243/com.github.leon.recycleviewdemo W/recycleviewdem: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
09-26 14:16:09.215 24243-24243/com.github.leon.recycleviewdemo D/OpenGLRenderer: Skia GL Pipeline
09-26 14:16:09.671 24243-24261/com.github.leon.recycleviewdemo I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
    android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
09-26 14:16:09.671 24243-24261/com.github.leon.recycleviewdemo I/OpenGLRenderer: Initialized EGL, version 1.4
09-26 14:16:09.672 24243-24261/com.github.leon.recycleviewdemo D/OpenGLRenderer: Swap behavior 1
09-26 14:16:09.672 24243-24261/com.github.leon.recycleviewdemo W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
09-26 14:16:09.673 24243-24261/com.github.leon.recycleviewdemo D/OpenGLRenderer: Swap behavior 0
09-26 14:16:09.675 24243-24261/com.github.leon.recycleviewdemo D/EGL_emulation: eglCreateContext: 0xe4a052a0: maj 3 min 0 rcv 3
09-26 14:16:09.713 24243-24261/com.github.leon.recycleviewdemo D/EGL_emulation: eglMakeCurrent: 0xe4a052a0: ver 3 0 (tinfo 0xe4a03690)
09-26 14:16:09.732 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:09.748 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=0, pool.size()=0
09-26 14:16:09.757 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:09.760 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=1, pool.size()=0
09-26 14:16:09.764 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:09.766 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=2, pool.size()=0
09-26 14:16:09.769 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:09.822 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=3, pool.size()=0
09-26 14:16:09.832 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:09.875 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=4, pool.size()=0
09-26 14:16:09.882 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:09.885 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=5, pool.size()=0
09-26 14:16:09.887 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:09.898 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=6, pool.size()=0
09-26 14:16:09.916 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:09.932 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=7, pool.size()=0
09-26 14:16:09.947 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:10.034 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=8, pool.size()=0
09-26 14:16:10.042 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:10.045 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=0, pool.size()=0
09-26 14:16:10.047 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:10.050 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=1, pool.size()=0
09-26 14:16:10.053 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:10.055 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=2, pool.size()=0
09-26 14:16:10.057 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:10.064 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=3, pool.size()=0
09-26 14:16:10.067 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:10.071 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=4, pool.size()=0
09-26 14:16:10.075 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:10.081 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=5, pool.size()=0
09-26 14:16:10.083 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:10.087 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=6, pool.size()=0
09-26 14:16:10.094 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:10.096 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=7, pool.size()=0
09-26 14:16:10.101 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:10.108 24243-24243/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=8, pool.size()=0
09-26 14:16:10.174 24243-24261/com.github.leon.recycleviewdemo D/EGL_emulation: eglMakeCurrent: 0xe4a052a0: ver 3 0 (tinfo 0xe4a03690)
09-26 14:16:11.303 24243-24243/com.github.leon.recycleviewdemo V/StudioProfiler: StudioProfilers agent attached.
09-26 14:16:11.368 24243-24303/com.github.leon.recycleviewdemo V/StudioProfiler: Acquiring Application for Events
09-26 14:16:11.496 24243-24243/com.github.leon.recycleviewdemo V/StudioProfiler: Transformed class: java/net/URL
09-26 14:16:11.496 24243-24243/com.github.leon.recycleviewdemo W/recycleviewdem: Current dex file has more than one class in it. Calling RetransformClasses on this class might fail if no transformations are applied to it!
09-26 14:16:11.824 24243-24243/com.github.leon.recycleviewdemo V/StudioProfiler: Memory control stream started.
09-26 14:16:13.446 24243-24310/com.github.leon.recycleviewdemo V/StudioProfiler: Live memory tracking disabled.
09-26 14:16:13.448 24243-24310/com.github.leon.recycleviewdemo V/StudioProfiler: Live memory tracking enabled.
    JNIEnv not attached
09-26 14:16:13.621 24243-24310/com.github.leon.recycleviewdemo V/StudioProfiler: Loaded classes: 11321
09-26 14:16:13.836 24243-24310/com.github.leon.recycleviewdemo V/StudioProfiler: Tracking initialization took: 388413000ns
09-26 14:16:14.222 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:14.269 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=0, pool.size()=0
09-26 14:16:14.296 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:14.363 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=1, pool.size()=0
09-26 14:16:14.417 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:14.455 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=2, pool.size()=0
09-26 14:16:14.493 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:14.533 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=3, pool.size()=0
09-26 14:16:14.558 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:14.580 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=4, pool.size()=0
09-26 14:16:14.609 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:14.714 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=5, pool.size()=0
09-26 14:16:14.734 24243-24254/com.github.leon.recycleviewdemo I/recycleviewdem: Background concurrent copying GC freed 338(167KB) AllocSpace objects, 0(0B) LOS objects, 49% free, 2MB/4MB, paused 272us total 118.222ms
09-26 14:16:14.740 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:14.761 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=6, pool.size()=0
09-26 14:16:14.778 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:14.801 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=7, pool.size()=0
09-26 14:16:14.823 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:14.840 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=8, pool.size()=0
09-26 14:16:14.863 24243-24243/com.github.leon.recycleviewdemo I/Choreographer: Skipped 40 frames!  The application may be doing too much work on its main thread.
09-26 14:16:14.864 24243-24261/com.github.leon.recycleviewdemo I/OpenGLRenderer: Davey! duration=832ms; Flags=0, IntendedVsync=34109002268542, Vsync=34109152268536, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=34109157365496, AnimationStart=34109157398496, PerformTraversalsStart=34109157653496, DrawStart=34109829017496, SyncQueued=34109831801496, SyncStart=34109831834496, IssueDrawCommandsStart=34109831907496, SwapBuffers=34109832442496, FrameCompleted=34109835032496, DequeueBufferDuration=47000, QueueBufferDuration=1894000, 
09-26 14:16:17.206 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:17.225 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=0, pool.size()=0
09-26 14:16:17.243 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:17.262 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=1, pool.size()=0
09-26 14:16:17.284 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:17.306 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=2, pool.size()=0
09-26 14:16:17.326 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:17.355 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=3, pool.size()=0
09-26 14:16:17.373 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:17.393 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=4, pool.size()=0
09-26 14:16:17.411 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:17.425 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=5, pool.size()=0
09-26 14:16:17.438 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:17.457 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=6, pool.size()=0
09-26 14:16:17.469 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:17.489 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=7, pool.size()=0
09-26 14:16:17.502 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:17.517 24243-24243/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=8, pool.size()=0
09-26 14:16:19.453 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:19.475 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=0, pool.size()=0
09-26 14:16:19.493 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:19.512 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=1, pool.size()=0
09-26 14:16:19.525 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:19.544 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=2, pool.size()=0
09-26 14:16:19.562 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:19.580 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=3, pool.size()=0
09-26 14:16:19.606 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:19.625 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=4, pool.size()=0
09-26 14:16:19.639 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:19.652 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=5, pool.size()=0
09-26 14:16:19.665 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:19.677 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=6, pool.size()=0
09-26 14:16:19.689 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:19.704 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=7, pool.size()=0
09-26 14:16:19.718 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:19.733 24243-24243/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=8, pool.size()=0

由于ViewPager默认缓存左右两个fragment,所以进行fragment切换的时候,每次tab0和tab2都会重新生成,对应的onCreateViewHolderonBindViewHolder都会执行

公用RecycledViewPool的情况下

09-26 14:16:52.800 24723-24723/? I/recycleviewdem: Not late-enabling -Xcheck:jni (already on)
09-26 14:16:52.820 24723-24723/? W/recycleviewdem: Unexpected CPU variant for X86 using defaults: x86
09-26 14:16:53.493 24723-24723/com.github.leon.recycleviewdemo W/recycleviewdem: JIT profile information will not be recorded: profile file does not exits.
09-26 14:16:53.503 24723-24723/com.github.leon.recycleviewdemo I/chatty: uid=10087(com.github.leon.recycleviewdemo) identical 10 lines
09-26 14:16:53.505 24723-24723/com.github.leon.recycleviewdemo W/recycleviewdem: JIT profile information will not be recorded: profile file does not exits.
09-26 14:16:53.640 24723-24723/com.github.leon.recycleviewdemo I/InstantRun: starting instant run server: is main process
09-26 14:16:54.092 24723-24723/com.github.leon.recycleviewdemo W/recycleviewdem: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
09-26 14:16:54.093 24723-24723/com.github.leon.recycleviewdemo W/recycleviewdem: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
09-26 14:16:54.246 24723-24723/com.github.leon.recycleviewdemo D/OpenGLRenderer: Skia GL Pipeline
09-26 14:16:54.389 24723-24747/com.github.leon.recycleviewdemo I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
    android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
09-26 14:16:54.389 24723-24747/com.github.leon.recycleviewdemo I/OpenGLRenderer: Initialized EGL, version 1.4
09-26 14:16:54.389 24723-24747/com.github.leon.recycleviewdemo D/OpenGLRenderer: Swap behavior 1
09-26 14:16:54.390 24723-24747/com.github.leon.recycleviewdemo W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
09-26 14:16:54.390 24723-24747/com.github.leon.recycleviewdemo D/OpenGLRenderer: Swap behavior 0
09-26 14:16:54.391 24723-24747/com.github.leon.recycleviewdemo D/EGL_emulation: eglCreateContext: 0xe20171e0: maj 3 min 0 rcv 3
09-26 14:16:54.393 24723-24747/com.github.leon.recycleviewdemo D/EGL_emulation: eglMakeCurrent: 0xe20171e0: ver 3 0 (tinfo 0xea9e0330)
09-26 14:16:54.420 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:54.430 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=0, pool.size()=0
09-26 14:16:54.433 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:54.444 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=1, pool.size()=0
09-26 14:16:54.447 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:54.455 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=2, pool.size()=0
09-26 14:16:54.459 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:54.462 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=3, pool.size()=0
09-26 14:16:54.463 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:54.466 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=4, pool.size()=0
09-26 14:16:54.476 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:54.477 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=5, pool.size()=0
09-26 14:16:54.479 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:54.480 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=6, pool.size()=0
09-26 14:16:54.482 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:54.484 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=7, pool.size()=0
09-26 14:16:54.489 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onCreateViewHolder: pool.size()=0
09-26 14:16:54.492 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=8, pool.size()=0
09-26 14:16:54.494 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:54.496 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=0, pool.size()=0
09-26 14:16:54.497 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:54.499 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=1, pool.size()=0
09-26 14:16:54.500 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:54.508 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=2, pool.size()=0
09-26 14:16:54.511 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:54.514 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=3, pool.size()=0
09-26 14:16:54.515 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:54.517 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=4, pool.size()=0
09-26 14:16:54.518 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:54.521 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=5, pool.size()=0
09-26 14:16:54.525 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:54.527 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=6, pool.size()=0
09-26 14:16:54.529 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:54.532 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=7, pool.size()=0
09-26 14:16:54.534 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onCreateViewHolder: pool.size()=0
09-26 14:16:54.536 24723-24723/com.github.leon.recycleviewdemo E/liang: 1==onBindViewHolder: position=8, pool.size()=0
09-26 14:16:54.574 24723-24747/com.github.leon.recycleviewdemo D/EGL_emulation: eglMakeCurrent: 0xe20171e0: ver 3 0 (tinfo 0xea9e0330)
09-26 14:16:55.551 24723-24723/com.github.leon.recycleviewdemo V/StudioProfiler: StudioProfilers agent attached.
09-26 14:16:55.603 24723-24785/com.github.leon.recycleviewdemo V/StudioProfiler: Acquiring Application for Events
09-26 14:16:55.683 24723-24723/com.github.leon.recycleviewdemo V/StudioProfiler: Transformed class: java/net/URL
09-26 14:16:55.683 24723-24723/com.github.leon.recycleviewdemo W/recycleviewdem: Current dex file has more than one class in it. Calling RetransformClasses on this class might fail if no transformations are applied to it!
09-26 14:16:56.075 24723-24723/com.github.leon.recycleviewdemo V/StudioProfiler: Memory control stream started.
09-26 14:16:57.644 24723-24790/com.github.leon.recycleviewdemo V/StudioProfiler: Live memory tracking disabled.
09-26 14:16:57.646 24723-24790/com.github.leon.recycleviewdemo V/StudioProfiler: Live memory tracking enabled.
09-26 14:16:57.647 24723-24790/com.github.leon.recycleviewdemo V/StudioProfiler: JNIEnv not attached
09-26 14:16:57.790 24723-24790/com.github.leon.recycleviewdemo V/StudioProfiler: Loaded classes: 11321
09-26 14:16:58.046 24723-24790/com.github.leon.recycleviewdemo V/StudioProfiler: Tracking initialization took: 399721000ns
09-26 14:16:58.116 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:58.147 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=0, pool.size()=0
09-26 14:16:58.166 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:58.233 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=1, pool.size()=0
09-26 14:16:58.246 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:58.309 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=2, pool.size()=0
09-26 14:16:58.326 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:58.362 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=3, pool.size()=0
09-26 14:16:58.378 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:58.400 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=4, pool.size()=0
09-26 14:16:58.412 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:58.437 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=5, pool.size()=0
09-26 14:16:58.447 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:58.467 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=6, pool.size()=0
09-26 14:16:58.538 24723-24744/com.github.leon.recycleviewdemo I/recycleviewdem: Waiting for a blocking GC ProfileSaver
09-26 14:16:58.602 24723-24736/com.github.leon.recycleviewdemo I/recycleviewdem: Background concurrent copying GC freed 354(174KB) AllocSpace objects, 0(0B) LOS objects, 50% free, 2MB/5MB, paused 194us total 410.560ms
09-26 14:16:58.602 24723-24744/com.github.leon.recycleviewdemo I/recycleviewdem: WaitForGcToComplete blocked ProfileSaver on SystemWeakHolder for 63.768ms
09-26 14:16:58.618 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:58.656 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=7, pool.size()=0
09-26 14:16:58.695 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onCreateViewHolder: pool.size()=0
09-26 14:16:58.724 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=8, pool.size()=0
09-26 14:16:58.739 24723-24723/com.github.leon.recycleviewdemo I/Choreographer: Skipped 38 frames!  The application may be doing too much work on its main thread.
09-26 14:16:58.740 24723-24747/com.github.leon.recycleviewdemo I/OpenGLRenderer: Davey! duration=902ms; Flags=0, IntendedVsync=34152807833842, Vsync=34153057833832, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=34153068662496, AnimationStart=34153068693496, PerformTraversalsStart=34153068913496, DrawStart=34153706075496, SyncQueued=34153708065496, SyncStart=34153708172496, IssueDrawCommandsStart=34153708245496, SwapBuffers=34153708699496, FrameCompleted=34153710748496, DequeueBufferDuration=102000, QueueBufferDuration=1376000, 
09-26 14:17:00.723 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=0, pool.size()=8
09-26 14:17:00.732 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=1, pool.size()=7
09-26 14:17:00.737 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=2, pool.size()=6
09-26 14:17:00.741 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=3, pool.size()=5
09-26 14:17:00.746 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=4, pool.size()=4
09-26 14:17:00.753 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=5, pool.size()=3
09-26 14:17:00.762 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=6, pool.size()=2
09-26 14:17:00.765 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=7, pool.size()=1
09-26 14:17:00.776 24723-24723/com.github.leon.recycleviewdemo E/liang: 0==onBindViewHolder: position=8, pool.size()=0
09-26 14:17:02.773 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=0, pool.size()=8
09-26 14:17:02.781 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=1, pool.size()=7
09-26 14:17:02.786 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=2, pool.size()=6
09-26 14:17:02.795 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=3, pool.size()=5
09-26 14:17:02.800 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=4, pool.size()=4
09-26 14:17:02.805 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=5, pool.size()=3
09-26 14:17:02.808 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=6, pool.size()=2
09-26 14:17:02.813 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=7, pool.size()=1
09-26 14:17:02.821 24723-24723/com.github.leon.recycleviewdemo E/liang: 2==onBindViewHolder: position=8, pool.size()=0

同样的操作,因为公用了RecycledViewPool,所以切换过程中只调用了onBindViewHolder,效果很明显

测试代码

package com.github.leon.recycleviewdemo

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.support.design.widget.TabLayout
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentPagerAdapter
import android.support.v4.view.ViewPager
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var tabLayout = findViewById<TabLayout>(R.id.tabLayout)
        tabLayout.addTab(tabLayout.newTab().setText("1111"))
        tabLayout.addTab(tabLayout.newTab().setText("2222"))
        tabLayout.addTab(tabLayout.newTab().setText("3333"))

        var viewPager = findViewById<ViewPager>(R.id.viewPager)

        viewPager.adapter = PageAdapter(supportFragmentManager, tabLayout.tabCount)
        viewPager.addOnPageChangeListener(object : TabLayout.TabLayoutOnPageChangeListener(tabLayout) {
            override fun onPageSelected(position: Int) {
                super.onPageSelected(position)
            }
        })

        tabLayout.setOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
            override fun onTabReselected(p0: TabLayout.Tab?) {
            }

            override fun onTabUnselected(p0: TabLayout.Tab?) {
            }

            override fun onTabSelected(p0: TabLayout.Tab) {
                viewPager.currentItem = p0.position
            }
        })
    }
}

class PageAdapter(fm: FragmentManager, val num: Int) : FragmentPagerAdapter(fm) {

    override fun getItem(p0: Int): Fragment {
        return createFragment(p0)
    }

    override fun getCount(): Int {
        return num
    }

    private fun createFragment(pos: Int): Fragment {
        return TestFragment.newInstance(pos)
    }

}

class TestFragment() : Fragment() {

    companion object {
        fun newInstance(pos: Int): TestFragment {
            val fg = TestFragment()
            val bundle = Bundle()
            bundle.putInt("pos", pos)
            fg.arguments = bundle
            return fg
        }

        var recycledViewPool = MyRecycledViewPool()
    }

    var fragmentPosition: Int = -1
    lateinit var recyclerView: RecyclerView
    var mDatas = arrayListOf<String>("1", "2", "3", "4", "5", "11", "12", "13", "14", "15", "1", "2", "3", "4", "5", "11", "12", "13", "14", "15")

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_test, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)


        fragmentPosition = arguments?.get("pos") as Int
        recyclerView = view.findViewById(R.id.recycleView);
        var linearLayoutManager = LinearLayoutManager(activity)
        linearLayoutManager.recycleChildrenOnDetach = true
        recyclerView.layoutManager = linearLayoutManager
        TestFragment.recycledViewPool.setMaxRecycledViews(0, 10)
        recyclerView.setRecycledViewPool(TestFragment.recycledViewPool)
        var adapter = TestAdapter(mDatas, fragmentPosition)
        recyclerView.adapter = adapter

    }

    class TestAdapter(val datas: ArrayList<String>, val fragmentPosition: Int) : RecyclerView.Adapter<MyViewHolder>() {
        override fun getItemCount(): Int {
            return datas.size
        }

        override fun onBindViewHolder(viewHolder: MyViewHolder, position: Int) {
            Log.e("liang", "${fragmentPosition}==onBindViewHolder: position=$position, pool.size()=${TestFragment.recycledViewPool.getRecycledViewCount(0)}")
            viewHolder.tv.text = datas.get(position)
        }

        override fun onCreateViewHolder(parent: ViewGroup, position: Int): MyViewHolder {
            Log.e("liang", "${fragmentPosition}==onCreateViewHolder: pool.size()=${TestFragment.recycledViewPool.getRecycledViewCount(0)}")

            var holder = MyViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.item_home, parent, false))
            return holder
        }

    }

}

class MyRecycledViewPool : RecyclerView.RecycledViewPool() {

    var num = 0
    override fun getRecycledView(viewType: Int): RecyclerView.ViewHolder? {
        return super.getRecycledView(viewType)
    }

    override fun putRecycledView(scrap: RecyclerView.ViewHolder?) {
        super.putRecycledView(scrap)
    }
}

class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {

    var tv: TextView = view.findViewById(R.id.textView)

}


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容