ViewPager的SetCurrentItem方法导致异常

5
我遇到了一个奇怪的问题,已经花费三个小时无法解决。因此,我需要帮助。我正在创建一个类似于播放音乐中的PlayerUI。Activity具有ViewPager,并基于PlayLists中的曲目准备片段列表,允许用户使用滑动或片段UI上的下一曲和上一曲按钮切换曲目。
滑动功能都很好。在我的上一个和下一个按钮中,我调用ViewPager上的setCurrentItem,并根据从viewPager获取的值增加或减少计数。问题是下一个工作良好,但是当我在倒数第二个项目上点击下一个时,它会抛出异常。同样适用于前一个按钮。它运行良好,但是当我在第二个片段上单击上一个时,它会抛出异常。
这是我的错误日志:
java.lang.NullPointerException: Attempt to read from field 'int android.view.View.mViewFlags' on a null object reference
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3366)
        at android.view.View.updateDisplayListIfDirty(View.java:14127)
        at android.view.View.getDisplayList(View.java:14189)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3389)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3368)
        at android.view.View.updateDisplayListIfDirty(View.java:14127)
        at android.view.View.getDisplayList(View.java:14189)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3389)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3368)
        at android.view.View.updateDisplayListIfDirty(View.java:14127)
        at android.view.View.getDisplayList(View.java:14189)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3389)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3368)
        at android.view.View.updateDisplayListIfDirty(View.java:14127)
        at android.view.View.getDisplayList(View.java:14189)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3389)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3368)
        at android.view.View.updateDisplayListIfDirty(View.java:14127)
        at android.view.View.getDisplayList(View.java:14189)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3389)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3368)
        at android.view.View.updateDisplayListIfDirty(View.java:14127)
        at android.view.View.getDisplayList(View.java:14189)
        at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3389)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3368)
        at android.view.View.updateDisplayListIfDirty(View.java:14127)
        at android.view.View.getDisplayList(View.java:14189)
        at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:273)
        at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:279)
        at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:318)
        at android.view.ViewRootImpl.draw(ViewRootImpl.java:2530)
        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2352)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1982)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
        at android.view.Choreographer.doCallbacks(Choreographer.java:580)
        at android.view.Choreographer.doFrame(Choreographer.java:550)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

这是我的 Activity 代码,fragments 是我设置在视图页面上的片段列表。

ViewPagerAdapter adapter = new       ViewPagerAdapter(getSupportFragmentManager(),fragments);
adapter.setTrackList(trackList);
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(0);
viewPager.setCurrentItem(currentTrack.getPosition());

当用户按下“上一页”或“下一页”按钮(这些按钮位于片段中)时,我只需要执行以下操作之一:
((PlayerActivity)getActivity()).viewPager.setCurrentItem(((PlayerActivity)getActivity()).viewPager.getCurrentItem()+1);

((PlayerActivity)getActivity()).viewPager.setCurrentItem(((PlayerActivity)getActivity()).viewPager.getCurrentItem()-1);

可能出现了什么问题?

不要在Fragment中使用viewPager.getCurrentItem()。它只能在FragmentActivity中使用。 - eurosecom
@eurosecom 这不正确,它在片段中起作用。 - eyadMhanna
@user983327 你确定你没有超出viewpager中片段的范围吗? - eyadMhanna
2个回答

2

0
你之所以会遇到这个错误,是因为你超出了ViewPager中片段数量的范围。当你处于最后一个项目并点击下一步按钮时,你应该设置currentItem(0)。

这样不行。假设我有4个片段,我现在在第3个片段,需要跳转到第4个片段。我调用setCurrentItem并给出第四个片段的位置,我使用setCurrentItem(getCurrentItem() +1)来实现。所以位置是正确的。错误发生在从第3个到第4个的跳转时。所以这是正确的操作,为什么会出现错误是问题所在。请看下面我的答案,将对setCurrentItem的调用延迟100毫秒,这对我有效。 - user983327
你的ViewPager中的片段数量是静态的还是动态的? - eyadMhanna
动态的...根据用户在前一个活动中的选择而变化。 - user983327
你的问题是一样的,ViewPager 中没有返回最后一个项目的方法,因此你应该从前一个活动中传递片段数量参数,并按照答案中提到的处理该数字。假设你有四个片段,在第四个片段时,你应该将当前项目设置为 0。 - eyadMhanna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接