onPageSelected doesn't work for first page

AndroidAndroid Viewpager

Android Problem Overview


My pager adapter ( extends PagerAdepter ) has a textview in it. And I update this textview with MainActivity's onPageSelected . Its update textview for position > 0 , but start page (position 0) doesn't update on startup. When I swipe forward then swipe back; it sets value for position 0 BUT I couldnt set value ON START. How can set value for star page ?

public void onPageSelected(int position) {
			
			 switch (position) {
				case 0:	

					 PagerAdapter.tv.setText("value"); // => doesnt work on start
		
					break;

	                        default:
		                           PagerAdapter.tv.setText("value");
                                         break;
}
}

Full Code:

public class QuizStart extends SlidingFragmentActivity {
 @Override
	    protected void onCreate(final Bundle savedInstanceState) {
	        super.onCreate(savedInstanceState);
	       
	  	   this.setContentView(R.layout.activity_main);
	  
              mPager = (ViewPager)findViewById(R.id.pager);	        
	        QuestionPagerAdapter mAdapter = new QuestionPagerAdapter();
	       
	        mPager.setAdapter(mAdapter);
	        QuizStart.onPageSelected(0);
	    
	     mPager.setOnPageChangeListener(new OnPageChangeListener() {
          
                  
			@Override
			public void onPageScrollStateChanged(int arg0) { }

			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) { }

			@Override
			public void onPageSelected(int position) {
			
			 switch (position) {
				case 0:	

					 PagerAdapter.tv.setText("value"); // => doesnt work on start
		
					break;

	                        default:
		                           PagerAdapter.tv.setText("value");
                                         break;
				}
			}

		});
}
}

Android Solutions


Solution 1 - Android

You can manually call onPageSelected(0) when you create your OnPageChangeListener to set the starting state:

OnPageChangeListener pageChangeListener = new OnPageChangeListener() {
	@Override
	public void onPageScrollStateChanged(int arg0) { }

	@Override
	public void onPageScrolled(int arg0, float arg1, int arg2) { }

	@Override
	public void onPageSelected(int position) {
			
		switch (position) {
		case 0:	
			QuizStart.next.setText(getmycurrentpage()+"");
			break;
				
		default:
								 
			QuizStart.next.setText(getmycurrentpage()+"");
			break;
		}
	}
});

   mPager.setOnPageChangeListener(pageChangeListener);
   // do this in a runnable to make sure the viewPager's views are already instantiated before triggering the onPageSelected call
   mPager.post(new Runnable()
   {
       @Override
       public void run() 
       {
           pageChangeListener .onPageSelected(viewPager.getCurrentItem());
       }
   });

Edit

Now it will not get Null Pointer exception as pointed by @metemet06

Solution 2 - Android

For me work next code

    viewPager.addOnPageChangeListener(myOnPageChangeListener);

.

    ViewPager.OnPageChangeListener myOnPageChangeListener = new ViewPager.OnPageChangeListener() {

    //declare key
    Boolean first = true;

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if (first && positionOffset == 0 && positionOffsetPixels == 0){
            onPageSelected(0);
            first = false;
        }
    }

    @Override
    public void onPageSelected(int position) {
        //do what need
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }
};

Solution 3 - Android

My solution was to extend pager adapter and create an interface inside it. Then make the adapter call the interface only once after creating the adapter. Inside interface callback you can call onPageChanged method without having nullpointerexception. Add this class to your project and extend your adapter from it. Dont forget to set listener to adapter before setting adapter to viewpager. Adapter class below:

public abstract class ExtendedPagerAdapter extends FragmentPagerAdapter {

private boolean instantiated;
private AdapterListener adapterListener;

public interface AdapterListener {
    void onAdapterInstantiated();
}

public ExtendedPagerAdapter(FragmentManager fragmentManager) {
    this(fragmentManager, null);
}

public ExtendedPagerAdapter(FragmentManager fragmentManager, AdapterListener adapterListener) {
    super(fragmentManager);
    this.adapterListener = adapterListener;
    instantiated = false;
}

@Override
public void finishUpdate(ViewGroup container) {
    super.finishUpdate(container);
    if (!instantiated) {
        instantiated = true;
        if (adapterListener != null) {
            adapterListener.onAdapterInstantiated();
        }
    }
}

public void setAdapterInstantiatedListener(AdapterListener adapterListener) {
    this.adapterListener = adapterListener;
}
}

Solution 4 - Android

I fixed the issue in my app by adding the code that should be executed for the first page in the onCreate()-method of my activity.

Its not the prettiest hack and involves some redundant code, but as I only want to load some text data when the pages are changing it is the easiest way to do it in my case.

Calling onPageSelected() manually caused NullPointerExceptions, just das described in other comments above.

Solution 5 - Android

It seems to me that what you really want to be doing is overriding getPageTitle(), and then, somewhere else, grabbing that page title and setting it as a TextView's text.

That way when you initialize your activity, initialize the PagerAdapter and call getTitle(0). This will get you the title for page 0. Now set that in the Activity's textview. Later, whenever you change pages just call getTitle(newPosition) and update that TextView.

Solution 6 - Android

You probably use some AsyncTasks to load the dataset and it is hard to determine which task will be the last to finish. And only after that last task, when the whole dataset is complete you could call OnPageSelected, because it is doing a flush on the UI over the whole dataset.

Instead of calling the OnPageSelected-function manually when the page is loaded the first time, rather build up the UI step by step the "normal"-way. Later on, when the user changes the page, the dataset should be complete and it is save to let the update been made in the OnPageSelected-function.

Solution 7 - Android

Because I did what was suggested here and it did not work I will post what did work for me was adding the instantiating function to onPageScrolled, like so:

   @Override
   public void onPageScrolled(int arg0, float arg1, int arg2) {
   
           adapter.closeText(arg0, viewPager);

	}

Probably the reason it worked is that onPagesScrolled is activated farther down the line of the android task manager, so we prevent the unwanted situation where the page is inflated with skipping the listeners attachment to the view.

Solution 8 - Android

Actually I found a good way based on this answer.

The problem is that the ViewPager is not fully loaded when the listener is setup, the first page is called but the fragments inside the ViewPager are not fully initialized yet.

In order to fix that I just keep a variable to know if the first page has been called or not:

private boolean mFirstPageCalled = false;

Then in the listener:

@Override
public void onPageSelected(int position) {

    if(mFirstPageCalled) {
        // Do your thing
    } else {
        mFirstPageCalled = true;
    }
}

The final thing to do is to handle the first page that has been missed, this can be done once the ViewPager has been fully created with:

    mViewPager.post(new Runnable(){
        @Override
        public void run() {
            // Do your thing
        }
    });

In my case I just call back here the current fragment showed and work on it:

Fragment currentFragment = mPagerAdapter.instantiateItem(mViewPager, mViewPager.getCurrentItem());
currentFragment.customAction();

The post method is only called once, so perfect to handle the first page case.

Solution 9 - Android

My solution is an extend ViewPager

class MyViewPager extends ViewPager {

    private List<OnPageChangeListener> _Listeners = new ArrayList<>();

    public MyViewPager(Context context) {
        super(context);
    }

    public MyViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void addOnPageChangeListener(OnPageChangeListener listener) {
        super.addOnPageChangeListener(listener);
        _Listeners.add(listener);
    }

    @Override
    public void removeOnPageChangeListener(OnPageChangeListener listener) {
        super.removeOnPageChangeListener(listener);
        _Listeners.remove(listener);
    }

    @Override
    public void setCurrentItem(final int item) {
        if (item != getCurrentItem()) {
            super.setCurrentItem(item);
        } else {
            post(new Runnable() {
                @Override
                public void run() {
                    dispatchOnPageSelected(item);
                }
            });
        }
    }

    private void dispatchOnPageSelected(int position) {
        for (int i = 0, size = _Listeners.size(); i < size; i++) {
            OnPageChangeListener listener = _Listeners.get(i);
            if (listener != null) {
                listener.onPageSelected(position);
            }
        }
    }
}

Solution 10 - Android

@Override
public void addOnPageChangeListener(@NonNull OnPageChangeListener listener) {
    super.addOnPageChangeListener(listener);
    if (getAdapter() != null && getAdapter().getCount() > 0) {
        post(() -> listener.onPageSelected(getCurrentItem()));
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionmetemet06View Question on Stackoverflow
Solution 1 - AndroidianhanniballakeView Answer on Stackoverflow
Solution 2 - AndroidИгорь БерезовскийView Answer on Stackoverflow
Solution 3 - AndroidArūnas BedžinskasView Answer on Stackoverflow
Solution 4 - AndroidLuigi_PapardelleView Answer on Stackoverflow
Solution 5 - AndroiddmonView Answer on Stackoverflow
Solution 6 - AndroidAlexander RoehnischView Answer on Stackoverflow
Solution 7 - AndroidsiviView Answer on Stackoverflow
Solution 8 - AndroidYoann HercouetView Answer on Stackoverflow
Solution 9 - Androidsteven274View Answer on Stackoverflow
Solution 10 - Androiderlei liuView Answer on Stackoverflow