一旦不再可见,如何在 ViewPager2 中重置 ViewHolder 的视图状态?
How to reset the view state of a ViewHolder in ViewPager2, once it is not visible anymore?
我正在使用 ViewPager2
和 ListAdapter
水平滚动浏览 Recycler.ViewHolder
项,一次显示一项。当内容不适合屏幕时,每个都可以垂直滚动。
一旦项目不再可见,我想重置它们的滚动状态,因为视图持有者可能会被另一个项目重用,而且它更整洁。
我知道如何在 ViewHolder
中重置滚动状态,但是我可以把这段代码放在哪里?
我首先想到它可能在托管 ViewPager2
的片段中,我可以在其中注册回调 ViewPager2.OnPageChangeCallback
与 viewpager:
private var lastPosition = -1
private var callback = object: ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
if (lastPosition >= 0) {
// reset scroll here
val v: MyViewHolder = ???(position)
v.resetScrollState()
}
lastPosition = position
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewpager = binding.itemPager
viewpager.adapter = [...]
viewpager.registerOnPageChangeCallback(callback)
}
(其中 binding.itemPager
指向 ViewPager2
)
但我不知道如何轻松获取视图持有者,除非将其存储(例如在一个集合中)以便我可以从 position
检索它。然后我仍然必须第一次正确设置 lastPosition
但它是次要的。
我的问题:
有什么办法
- 将监听器设置为页面更改,并访问视图持有者?
- 或者,在
position
? 的函数中检索视图持有者
或者有更好的方法来处理这个问题吗?
我终于找到了。
对于给定的 lastPosition
,可以通过以下方式获取视图持有者:
(viewpager.get(0) as RecyclerView).findViewHolderForAdapterPosition(lastPosition)
as? MyViewHolder
所以回调变成:
private var callback = object: ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
if (lastPosition >= 0) {
// reset scroll here
val holder = (viewpager.get(0) as RecyclerView).findViewHolderForAdapterPosition(lastPosition) as? TodoEventAdapter.MyViewHolder
if (holder != null)
holder.resetScroll()
}
lastPosition = position
}
}
我可以设置 lastPosition
的初始值并注册回调,例如在带有 ViewPager2.currentItem
的片段代码中:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewpager = binding.itemPager
[...]
lastPosition = viewpager.currentItem
viewpager.registerOnPageChangeCallback(callback)
}
override fun onDestroyView() {
[...]
viewpager.unregisterOnPageChangeCallback(callback)
super.onDestroyView()
}
其中binding.itemPager
使用viewBinding,对应layout的ViewPager2实例
请注意,要显示的第一个位置可能来自参数,例如需要在起始位置显示特定项目的 activity。 lastPosition
的初始值可以从这个参数中得到,也可以从已经设置的ViewPager2.currentItem
值once/if中得到,如上图
我正在使用 ViewPager2
和 ListAdapter
水平滚动浏览 Recycler.ViewHolder
项,一次显示一项。当内容不适合屏幕时,每个都可以垂直滚动。
一旦项目不再可见,我想重置它们的滚动状态,因为视图持有者可能会被另一个项目重用,而且它更整洁。
我知道如何在 ViewHolder
中重置滚动状态,但是我可以把这段代码放在哪里?
我首先想到它可能在托管 ViewPager2
的片段中,我可以在其中注册回调 ViewPager2.OnPageChangeCallback
与 viewpager:
private var lastPosition = -1
private var callback = object: ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
if (lastPosition >= 0) {
// reset scroll here
val v: MyViewHolder = ???(position)
v.resetScrollState()
}
lastPosition = position
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewpager = binding.itemPager
viewpager.adapter = [...]
viewpager.registerOnPageChangeCallback(callback)
}
(其中 binding.itemPager
指向 ViewPager2
)
但我不知道如何轻松获取视图持有者,除非将其存储(例如在一个集合中)以便我可以从 position
检索它。然后我仍然必须第一次正确设置 lastPosition
但它是次要的。
我的问题: 有什么办法
- 将监听器设置为页面更改,并访问视图持有者?
- 或者,在
position
? 的函数中检索视图持有者
或者有更好的方法来处理这个问题吗?
我终于找到了。
对于给定的 lastPosition
,可以通过以下方式获取视图持有者:
(viewpager.get(0) as RecyclerView).findViewHolderForAdapterPosition(lastPosition)
as? MyViewHolder
所以回调变成:
private var callback = object: ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
if (lastPosition >= 0) {
// reset scroll here
val holder = (viewpager.get(0) as RecyclerView).findViewHolderForAdapterPosition(lastPosition) as? TodoEventAdapter.MyViewHolder
if (holder != null)
holder.resetScroll()
}
lastPosition = position
}
}
我可以设置 lastPosition
的初始值并注册回调,例如在带有 ViewPager2.currentItem
的片段代码中:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewpager = binding.itemPager
[...]
lastPosition = viewpager.currentItem
viewpager.registerOnPageChangeCallback(callback)
}
override fun onDestroyView() {
[...]
viewpager.unregisterOnPageChangeCallback(callback)
super.onDestroyView()
}
其中binding.itemPager
使用viewBinding,对应layout的ViewPager2实例
请注意,要显示的第一个位置可能来自参数,例如需要在起始位置显示特定项目的 activity。 lastPosition
的初始值可以从这个参数中得到,也可以从已经设置的ViewPager2.currentItem
值once/if中得到,如上图