The PagerAdapter class calls several times

I am working on an application that has a ViewPager view, I created a PagerAdapter that has a view, the instantiateItem () method of the PagerAdapter is called twice in create (), I don’t know why, can anyone help me with this?

Here is my code

View PagerView; MyPagerAdapter adapter; ViewPager pager; adapter = new MyPagerAdapter(); pager.setAdapter(adapter); pager.setCurrentItem(0); public class MyPagerAdapter extends PagerAdapter { @Override public Object instantiateItem(final View collection, final int position) { Log.d("Inside", "Pager"); PagerView = new View(collection.getContext()); LayoutInflater inflater = (LayoutInflater) collection.getContext() .getSystemService(Context.LAYOUT_INFLATER_SERVICE); PagerView = inflater.inflate(R.layout.tablemenu, null, false); tbMenuDetails = (TableLayout) PagerView .findViewById(R.id.Menutable1); scrollview = (ScrollView) PagerView.findViewById(R.id.scrollView1); tbMenuDetails.removeAllViews(); removeTableRows(); createTableLayout(position); String str[][] = datasource.GetSubMenuDetailsFromMenuId(MenuIdlst .get(position).trim()); Log.d("Str", "" + str.length); for (int i = 0; i < str.length; i++) { addRows(str[i][1], str[i][2], str[i][0], str[i][3], position); Log.d("Message", "Pos " + position + " SubMenuName" + str[i][2] + " SubMenuId" + " " + str[i][0] + " TypeID" + " " + str[i][3]); } // View view = inflater.inflate(resId, null); ((ViewPager) collection).addView(PagerView, 0); return PagerView; } @Override public void destroyItem(final View arg0, final int arg1, final Object arg2) { ((ViewPager) arg0).removeView((View) arg2); } @Override public boolean isViewFromObject(final View arg0, final Object arg1) { return arg0 == ((View) arg1); } @Override public void finishUpdate(View arg0) { // TODO Auto-generated method stub } @Override public void restoreState(Parcelable arg0, ClassLoader arg1) { // TODO Auto-generated method stub } @Override public Parcelable saveState() { // TODO Auto-generated method stub return null; } @Override public void startUpdate(View arg0) { // TODO Auto-generated method stub } @Override public int getCount() { // TODO Auto-generated method stub return MenuIdlst.size(); } } 

Please, help

+7
source share
5 answers

If you decide to use fragments, do not use the PagerAdapter . Instead, continue with FragmentPagerAdapter or FragmentStatePagerAdapter :

 private class MyPagerAdapter extends FragmentStatePagerAdapter { public MyPagerAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return NUMBER_OF_PAGES_IN_PAGER; } @Override public Fragment getItem(int position) { // Implement the static method newInstance in MyFragment.java yourself. // It should return you a brand new instance of MyFragment, basically using // the code you had in your original instantiateItem method. return MyFragment.newInstance(position, ... etc ...); } } 

Then in your activity:

 myPagerAdapter = new MyPagerAdapter(getFragmentManager()); // or myPagerAdapter = new MyPagerAdapter(getSupportFragmentManager()); myViewPager.setAdapter(myPagerAdapter); 

To learn more about using snippets and ViewPagers: https://developer.android.com/reference/android/app/Fragment.html https://developer.android.com/reference/android/support/v4/view/ViewPager. html https://developer.android.com/reference/android/support/v4/app/FragmentStatePagerAdapter.html

+5
source

ViewPager by default preloads one page forward / in front of the current page (if any). You did not say if he was being called for the same or a different position.

+3
source

ViewPager.setOffscreenpageLimit (int) has a minimum value of 1. You can see this from the source code for ViewPager :

 private static final int DEFAULT_OFFSCREEN_PAGES = 1; ... /** * Set the number of pages that should be retained to either side of the * current page in the view hierarchy in an idle state. Pages beyond this * limit will be recreated from the adapter when needed. * * <p>This is offered as an optimization. If you know in advance the number * of pages you will need to support or have lazy-loading mechanisms in place * on your pages, tweaking this setting can have benefits in perceived smoothness * of paging animations and interaction. If you have a small number of pages (3-4) * that you can keep active all at once, less time will be spent in layout for * newly created view subtrees as the user pages back and forth.</p> * * <p>You should keep this limit low, especially if your pages have complex layouts. * This setting defaults to 1.</p> * * @param limit How many pages will be kept offscreen in an idle state. */ public void setOffscreenPageLimit(int limit) { if (limit < DEFAULT_OFFSCREEN_PAGES) { Log.w(TAG, "Requested offscreen page limit " + limit + " too small; defaulting to " + DEFAULT_OFFSCREEN_PAGES); limit = DEFAULT_OFFSCREEN_PAGES; } if (limit != mOffscreenPageLimit) { mOffscreenPageLimit = limit; populate(); } } 

You should see a warning in Logcat if you try to set it to zero.

The lower limit is 1 for a very good reason. When scrolling through the pager, the adjacent page should already be loaded, otherwise you will not see anything for the next page. If you manage to disable the marginal page off-screen, you will probably just see a black blank page when scrolling from the first page to the second. If you have a specific problem with the first and second pages being created at the beginning, try tweaking and fixing this.

+3
source

Use snippets for each view in the pager.

write the code below in the onCreate() method of FragmentActivity .

 List<Fragment> fragments = new Vector<Fragment>(); //for each fragment you want to add to the pager Bundle page = new Bundle(); page.putString("url", url); fragments.add(Fragment.instantiate(this,MyFragment.class.getName(),page)); //after adding all the fragments write the below lines this.mPagerAdapter = new PagerAdapter(super.getSupportFragmentManager(), fragments); mPager.setAdapter(this.mPagerAdapter); 

Sample fragment definition:

 public class MyFragment extends Fragment { public static MyFragment newInstance(String imageUrl) { final MyFragment mf = new MyFragment (); final Bundle args = new Bundle(); args.putString("somedata", "somedata"); mf.setArguments(args); return mf; } public MyFragment() {} @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String data = getArguments().getString("somedata"); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate and locate the main ImageView final View v = inflater.inflate(R.layout.my_fragment_view, container, false); //... return v; } 

I follow this method whenever I need to use ViewPager . Hope this helps. I could not understand why your instance creation method was called twice from the information you provided.

+2
source

Modify this to make it necessary for the isViewFromObject () method. This is very important, and it says that This method is necessary for the PagerAdapter to work properly.

 @Override public boolean isViewFromObject(View view, Object object) { if(object != null){ return ((Fragment)object).getView() == view; }else{ return false; } } 

You can look here .

-one
source

All Articles