问题描述
我通过 Viewpager2
使用 Tablyout
设置了 TabLayoutMediator
。 Viewpager2
的适配器是 RecyclerView.Adapter
我正在初始化 Viewpager2
和 Tablayout
,并将图像加载到标签中,如下所示:
myViewPager.apply {
offscreenPageLimit = 6
adapter = myRecycerViewAdapter
}
TabLayoutMediator(myTabLayout,myViewPager) { tab,position ->
val tabView: View =
LayoutInflater.from(context).inflate(R.layout.tab_magazine_preview,null)
Glide.with(context)
.load(urls[position])
.into(tabView.imageView)
tab.customView = tabView
}.attach()
现在此实现在初始化期间创建所有选项卡并将所有 urls
加载到选项卡中的 imageview
。这是一种消耗资源的方法,因为用户可能不会一直滑动到最后。如果我有大量的 url 列表,这会消耗更多资源。
Viewpager2
- offscreenPageLimit
有一个很好的功能,它有助于仅加载一定数量的相邻页面。我可以为 Tablayout 提供类似的功能吗?
解决方法
您可以使用 TabLayout
检测 View.OnScrollChangeListener
上的滑动手势
然后加载图像,但快速测试显示您需要在初始化可见选项卡时手动加载图像,因为没有滚动。
tabLayout.setOnScrollChangeListener { v,scrollX,scrollY,oldScrollX,oldScrollY ->
if (v is TabLayout) {
val scrollBounds = Rect()
v.getHitRect(scrollBounds)
for (i in 0 until v.tabCount) {
if (v.getTabAt(i)!!.view.getLocalVisibleRect(scrollBounds)) {
Log.i("!!!!!!!!!!","child visible at: " + i);
// check if image is not loaded/loading and load
} else {
Log.i("!!!!!!!!!!","child invisible: " + i);
}
}
}
}
旧答案。我误解了这个问题:
您可以通过侦听 ViewPager2.OnPageChangeCallback
并告诉所需片段根据页面位置加载其图像来实现这一点。
确保您的页面片段实现允许其加载图像的接口:
interface ILoadImage {
fun loadImage()
}
class MyPageFragment : Fragment(),ILoadImage {
private var isImageLoaded = false
override fun loadImage() {
if (isImageLoaded) return
/*
... load image
*/
isImageLoaded = true
}
}
然后在您的 myRecycerViewAdapter
创建函数中,该函数将接受选定的页面位置并更新片段
class MyRecycerViewAdapter /* ... */ {
val fragments: List<ILoadImage> = //...
fun loadImagesForPosition(position: Int) {
fragments[position].loadImage()
// also you can load images for next or prev fragments
}
}
最后监听 OnPageChangedCallback
并告诉适配器更新片段
myViewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
myRecycerViewAdapter.loadImagesForPosition(position)
}
})