Android 如何使ViewPager.arrowScroll()第一次工作?

Android 如何使ViewPager.arrowScroll()第一次工作?,android,android-viewpager,Android,Android Viewpager,我有一个ViewPager(使用FragmentStatePagerAdapter来分页片段)。用户可以使用左/右滑动从一个片段翻页到下一个片段;这个很好用。我还添加了分页按钮。这些的onClick监听器是通过以下方式实现的: mViewPager.arrowScroll(View.FOCUS_LEFT); 及 这在大多数情况下都有效:当用户点击时,视图按预期向左或向右滚动 但是在第一次点击>按钮时,什么也没有发生。我确实听到一声“咔嗒”声,确认点击发生了。我的日志语句显示调用了onClick

我有一个ViewPager(使用FragmentStatePagerAdapter来分页片段)。用户可以使用左/右滑动从一个片段翻页到下一个片段;这个很好用。我还添加了分页按钮。这些的onClick监听器是通过以下方式实现的:

mViewPager.arrowScroll(View.FOCUS_LEFT);

这在大多数情况下都有效:当用户点击时,视图按预期向左或向右滚动

但是在第一次点击>按钮时,什么也没有发生。我确实听到一声“咔嗒”声,确认点击发生了。我的日志语句显示调用了onClick侦听器,并且调用了
mviewpage.arrowcoll(View.FOCUS\u RIGHT)
。我甚至通过
arrowcoll()
检查返回的结果;这是真的!但是没有分页发生

在那之后,所有点击按钮都可以正常工作

为什么第一次调用
arrowsroll(View.FOCUS\u RIGHT)
没有效果,我如何修复它

我想我可以试着第一次调用它两次,但由于我不知道为什么没有发生记录在案的行为,我不知道这种方法是否会在某些手机或Android版本上导致双重分页

更新:一些日志记录
好了,我想我已经开始解决问题了。当我跟踪
ViewPager.arrowScroll(FOCUS\u RIGHT)
()时,它所做的似乎是首先尝试将焦点移到右侧(嗯,也许这解释了为什么参数说FOCUS\u RIGHT!)

这样,取决于当前的焦点,以及是否有一个NEXPROCESS视图在它的右边,它将把焦点移到那里,考虑它的任务完成,并返回到信号成功。 只有在右边没有nextFocus视图的情况下,它才会像我希望的那样使用pageRight()

在我的例子中,当我第一次按>,currentFocus=this.findFocus()返回null。然后它调用
nextFocused=FocusFinder.findNextFocus()
,并在当前显示的页面上生成一个列表视图。由于
currentFocus
为空且
nextFocus
不为空(除其他条件外),
arrowcoll()
满足将焦点设置为ListView的要求

第二次点击>,
currentFocus=this.findFocus()
返回列表视图,而
nextFocused=FocusFinder.findNextFocus()
生成空值。因为
nextFocused
为空,所以它不会尝试
nextFocused.requestFocus()
,而是调用
pageRight()
,这正是我首先想要的

在这种情况下,什么样的解决方案适合
ViewPager
的设计?听起来像是
arrowcoll()
并不像左/右按钮那样只用于左/右分页。相反,它意味着做键盘箭头键应该做的事情;因此得名

那么,应该使用什么方法来左/右翻页,而不考虑当前有什么或可以获得焦点

在调用
arrowcoll
之前,我可以通过将焦点设置为右视图来尝试解决
arrowcoll
的行为,但这似乎是一个难题。有
pageRight
pageLeft
两种方法,它们看起来完全符合我的需要,但它们不是公开的,也没有文档

好的,
pageRight
pageLeft
调用
setCurrentItem(mCurItem+或-1)
来完成他们的工作,这是一种公开且有文档记录的方法。所以我想我可以把
pageRight
pageLeft
的代码复制到我自己的代码中

这种API设计对我来说似乎很奇怪,因为在寻呼机屏幕上有左/右按钮是多么常见,无论焦点如何,都可以左/右翻页。同样令人沮丧的是,关于
arrowcoll()
和左/右分页ViewPager的文档非常模糊。
但无论如何,我认为我已经找到了一个不错的解决方案。

在适配器中添加一些调试/断点,它将为当前视图获取数据,如果它转到第二项,但不知何故没有显示,或者在此之前已经发生了一些事情,适配器再次被要求获取第一项。(也就是说,您只发布了关于UI端和事件的调试,似乎在那里,所以现在验证您的底层数据,如果它们对应于UI事件)(如果底层数据是正确的,我将检查的下一件事是某种缓存/视图循环)(我将使用“第一次调用分页两次”只有当我100%确定它是API错误,其他一切都是正确的时候,才有解决方案。但是从你提供的有限的帖子来看,有很多地方你的代码可能出了问题,你没有提供它们以供审查,特别是回收视图实例有点难正确编写)@Ped7g好的建议。我试试看。我肯定会检查adapter.getItem(position)是否被调用,调用位置是什么。
adapter.getItem(position)
在点击任何按钮之前立即被调用位置0和1。这种提前获取行为与我以前看到的一致。当我第一次点击
时,不会调用
适配器.getItem(位置)
。当我再次点击
时,
adapter.getItem(2)
会在视图从第0页滚动到第1页时被调用,这同样与通常的提前获取行为一致。我能从中得出什么结论?对我来说,它只是说
arrowcoll(View.FOCUS\u RIGHT)
在第一次调用它时没有做任何事情。我还跟踪了
instantiateItem()
setPrimaryItem()
InstanceItem
遵循
getItem
:当且仅当调用
getItem(i)
时,才会使用相同的位置调用
InstanceItem(i)
<另一方面,code>setPrimaryItem跟踪可见页面。当我第一次点击
时,两个
getItem
n
mViewPager.arrowScroll(View.FOCUS_RIGHT);
// Before any button taps.
QuestionAdapter: getItem(0)
QuestionAdapter: instantiateItem: position 0
QuestionAdapter: getItem(1)
QuestionAdapter: instantiateItem: position 1
QuestionAdapter: setPrimaryItem: position 0
QuestionAdapter: setPrimaryItem: position 0
// The screen is displaying page 0.
// Now I tap the > button:
QuestionAdapter: setPrimaryItem: position 0
// The screen is still displaying page 0.
// Now I tap the > button again:
QuestionAdapter: getItem(2)
QuestionAdapter: instantiateItem: position 2
QuestionAdapter: setPrimaryItem: position 1
QuestionAdapter: setPrimaryItem: position 1
QuestionAdapter: setPrimaryItem: position 1
// Now the screen displays page 1.