【问题标题】:SetCurrentItem on ViewPager is causing exceptionViewPager 上的 SetCurrentItem 导致异常
【发布时间】:2015-08-19 00:29:52
【问题描述】:

我遇到了一个奇怪的问题,在过去三个小时内无法解决。所以我需要帮助。我正在创建一个类似于 Play Music 中的 PlayerUI。 Activity 有一个 ViewPager 并根据 PlayLists 中的曲目准备片段列表,并允许用户使用片段 UI 上的滑动或“下一个”和“上一个”按钮从一个曲目切换到另一个曲目。

滑动功能一切正常。在我的上一个和下一个按钮中,我在 viewPager 上调用 setCurrentItem 并根据来自 viewPager 的 getCurrentItem 的值增加或减少计数。问题是下一个效果很好,但是当我在最后一个项目之前点击下一个项目时会引发异常。与上一个按钮相同。它工作得很好,但是当我在第二个片段上单击上一个时它会引发异常。

这是我的错误日志::

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());

当用户单击 Next 和 Previous 按钮(位于片段中)时,我只需执行以下操作之一

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

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

可能是什么问题?

【问题讨论】:

  • 不要在片段中使用 viewPager.getCurrentItem()。它仅适用于 FragmentActivity,
  • @eurosecom 不正确,它适用于片段。
  • @user983327 你确定你没有超出viewpager中的片段数量吗?

标签: android android-fragments android-viewpager


【解决方案1】:
Runnable dirtyHack = new Runnable() {
        @Override
        public void run() {
            pager.setCurrentItem(2, 0);
        }
    };
    Handler handler = new Handler();
    handler.postDelayed(dirtyHack, 100);

...

可能布局还没有膨胀,所以我必须等待或获得NPE。请参考以下链接

https://code.google.com/p/android/issues/detail?id=75309

Android ViewPager setCurrentItem not working after onResume

setCurrentItem after setting adapter on GridViewPager return NPE

【讨论】:

    【解决方案2】:

    您收到此错误是因为您超出了 ViewPager 中的片段数量,当您在最后一个项目中并点击下一步按钮时,您应该设置 currentItem(0)

    【讨论】:

    • 这行不通。假设我有 4 个片段。我在第三个。现在我需要去第四个。我调用 setCurrentItem 并给出第四个的位置。顺便说一句,我像这样使用 setCurrentItem(getCurrentItem() +1)。所以位置是正确的。当我从第 3 到第 4 时发生错误。所以这是正确的做法,为什么会出现错误是问题所在。请参阅下面关于将 setCurrentItem 的调用延迟 100 毫秒的答案,这对我有用。
    • 你的ViewPager中的fragment数量是静态的还是动态的?
    • 动态..根据上一个活动中的用户选择进行更改。
    • 您的问题是一样的,ViewPager 中没有返回最后一项的方法,因此您应该传递上一个活动中的片段数参数并处理答案中提到的数字.假设您有四个片段,当您在第四个片段时,您应该将当前项目设置为 0
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多