5

Im having a wierd issue and not able to fix this in the last three hours. So I need help. Im creating a PlayerUI like the one in Play Music. The Activity has a ViewPager and prepares the list of fragments based on the tracks in the PlayLists and allows the user to switch from one track to another using the swipe or the Next and Previous buttons on the Fragment UI.

The swipe function all works good. And in my previous and next buttons im calling setCurrentItem on the viewPager and incrementing or decreasing the count based on the value from getCurrentItem from viewPager. The issue is the next works good however throws an exception when I hit next on the item prior to the last item. And same with previous button. It works great however it throws an exception when I click previous on the second fragment.

This is my error log::

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)

Here is the code for my Activity, fragments is the list of fragments that I set it on the view pager

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

When the user clicks on the Next and Previous buttons (which are in the fragments) I simply do one of the following

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

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

What could be the issue?

King of Masses
  • 18,405
  • 4
  • 60
  • 77
user983327
  • 933
  • 2
  • 8
  • 12

2 Answers2

1
Runnable dirtyHack = new Runnable() {
        @Override
        public void run() {
            pager.setCurrentItem(2, 0);
        }
    };
    Handler handler = new Handler();
    handler.postDelayed(dirtyHack, 100);

...

Probably the layout is not yet inflated, so I have to wait or get NPE. Please refer to the following links

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

Community
  • 1
  • 1
user983327
  • 933
  • 2
  • 8
  • 12
0

you are getting this error because you are going out of bounds of number of fragments in the ViewPager, when you are in the last item and you hit next button you should set currentItem(0)

eyadMhanna
  • 2,412
  • 3
  • 31
  • 49
  • This will not work. Say I have 4 fragments. Im at the 3rd one. Now I need to go to 4th one. I call the setCurrentItem and give the position of the fourth one. which by the way I use like this setCurrentItem(getCurrentItem() +1). So position is correct. The error happens when I go from 3rd to 4th. So its the right thing to do so why the error is coming is the question. Please see my answer below on delaying the call to setCurrentItem by 100 ms that worked for me. – user983327 Aug 19 '15 at 07:24
  • is the number of fragments in your ViewPager static or dynamic? – eyadMhanna Aug 19 '15 at 07:25
  • dynamic.. changes based on the user selection in the previous activity. – user983327 Aug 19 '15 at 07:26
  • your problem is the same, there is no method in ViewPager that returns the last item in it, so you should pass number of fragments parameter from the previous activity and deal with the number as mentioned in the answer. let's say you have four fragments, when your are at the fourth one you should set the current item to 0 – eyadMhanna Aug 19 '15 at 07:30