我正在使用ViewPager2创建幻灯片。例如,幻灯片显示有3个项目,我想在活动打开时显示第二个项目。我使用setCurrentItem(int item, boolean smoothScroll)
方法,但是它不起作用,什么也没发生。我该如何实现?
viewPager.adapter = adapter
viewPager.setCurrentItem(1, true)
答案 0 :(得分:19)
我认为一个更简单,更可靠的修复方法是推迟到下一个运行周期,而不是不安全的延迟,例如
viewPager.post {
viewPager.setCurrentItem(1, true)
}
答案 1 :(得分:4)
如上所述,您必须在 ViewPager2 上使用setCurrentItem(position, smoothScroll)
方法才能显示所选项目。要使其正常工作,您必须定义一个回调,下面是一个示例:
ViewPager2.OnPageChangeCallback callback = new ViewPager2.OnPageChangeCallback() {
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
}
};
然后您必须注册,如下所示:
viewPager.registerOnPageChangeCallback(callback);
也不要忘记取消注册:
viewPager.unregisterOnPageChangeCallback(callback);
当您调用setCurrentItem(position)
方法时,它将通过您的回调调用onPageSelected(int position)
方法,并传递您的参数,然后从createFragment(int position)
类中调用方法FragmentStateAdapter
将会显示您的片段。
答案 2 :(得分:3)
我尝试更改Handler().dely()
或viewPager2.post{}
中的viewpager2页面,甚至'viewPager2.get(0).post
也对我不起作用,我在{{1}中使用ViewPager
}和FragmentStateAdapter
。
对我有用的是将Tablayout
在RecylerView
中的位置{strong>手动绑定到ViewPager2
FragmentStateAdapter
为什么
我的问题是yourViewPager2View.adapter
中的 (yourViewPager2View[0] as RecyclerView).scrollToPosition(moveToTabNumber)
函数总是将片段从 0位置开始,无论我将页面设置为哪个pageNumber
onCreateFragment(position:Int):Fragmeet
我检查了在FragmentStateAdapter
中被调用的位置:
viewPager.setCurrentItem = pageNumber
所以我所要做的就是强制FragmentStateAdapter
用我想要的页码呼叫FragmentStateAdapter
。
答案 3 :(得分:3)
首先,我认为接受的答案(@hosseinAmini的答案)建议使用愚蠢的延迟来解决此问题,这是一个耻辱。首先,您应该寻找假定的错误是由什么引起的,而不是相信像这样的不合理的解决方案。
@Rune的建议是正确的;所以我在答案中引用了它的代码:
viewPager.post { viewPager.setCurrentItem(1, true) }
我唯一要争论的是上述人的信念,即其解决方案只是推迟了下一个运行周期中该lambda的执行。这不会使任何东西正常工作。相反,它实际上是在将视图附加到窗口后才将lambda的执行推迟到执行,这意味着它也已添加到父窗口中。确实,在将当前ViewPager2
项目附加到窗口之前,似乎存在一个问题。我在说什么的两个证据如下:
使用Handler
中的任何一个都几乎无法有效地工作。
Handler(Looper.getMainLooper()).post {
viewPager.setCurrentItem(1, true) // Not working properly
}
View.handler
获得null
,这表示该视图尚未附加到任何窗口。
View.handler // = null
答案 4 :(得分:3)
尝试使用 viewPager.setCurrentItem(1, false)
。那个'false'是关于smoothScroll,当你的活动刚打开时你不能平滑滚动你的viewPager2。在 onViewCreated() 方法中的片段上对其进行了测试,它也不适用于“true”,但适用于“false”
答案 5 :(得分:2)
mViewPager.setCurrentItem(1,true); --->这就像您上面写的那样
应该可以, 如有疑问,只需检查您的位置即可:
@Override
public void onPageSelected(int i) {
if (LOG_DEBUG) Log.v(TAG, " ++++++++ onPageSelected: " + i);
mViewPager.setCurrentItem(i);
//TODO You can use this position: to write other dependent logic
}
并检查
PagerAdapter中的getItem(int位置)
或者粘贴您的代码。
答案 6 :(得分:2)
setCurrentItem(int item, boolean smoothScroll)
在ViewPager
中可以正常工作,但在ViewPgar2
中则不能正常工作。最后,我通过将setCurrentItem(int item, boolean smoothScroll
)方法添加到这样的延迟中来解决此问题:
Handler().postDelayed({
view.viewPager.setCurrentItem(startPosition, false)
}, 100)
答案 7 :(得分:1)
首先,您需要在想要的任何侦听器或按钮下初始化Main活动,然后在其后放置此行。 这里MainActvity是您正在使用的Viewpager主类,而2是您要移动的位置
MainActivity main = (MainActivity ) mContext;
main.selectTab(2, true);
答案 8 :(得分:1)
请勿使用计时器,您可能会遇到许多可能的状态,即用户的电话速度较慢,实际上运行时间要长于100毫秒,而且,您也不想太慢的计时器使其变得不可靠。
下面,我们执行以下操作,将侦听器设置为ViewTreeObserver,然后等待,直到在ViewPager2的RecyclerView中布置了一定数量的子级为止(内部工作)。一旦确定已经布置了x项,就开始无动画滚动,从该位置开始。
val recyclerView = (Your ViewPager2).getChildAt(0)
recyclerView.apply {
val itemCount = adapter?.itemCount ?: 0
if(itemCount >= #(Position you want to scroll to)) {
viewTreeObserver.addOnGlobalLayoutListener(object: ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
viewTreeObserver.removeOnGlobalLayoutListener(this)
// False for without animation scroll
(Your ViewPager2).scrollToPosition(#PositionToStartAt, false)
}
}
}
答案 9 :(得分:0)
我遇到了同样的问题。在我的例子中,我让 viewPager2 默认消失,直到网络请求成功,我通过在使 viewPager2 可见后设置 CurrentItem 来修复它。