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(R.id.tabLayout)
        tabLayout.addTab(tabLayout.newTab().setText("1111"))
        tabLayout.addTab(tabLayout.newTab().setText("2222"))
        tabLayout.addTab(tabLayout.newTab().setText("3333"))

        var viewPager = findViewById(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("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, val fragmentPosition: Int) : RecyclerView.Adapter() {
        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)

}


你可能感兴趣的:(RecycledViewPool使用)