2

I am new with viewpager, i want to create view using viewpager, here all the things are dynamic, so i followed this way, My problem is that instantiateItem() is getting called twice oncreate.
Oncreate

{
    pager = (ViewPager) findViewById(R.id.panelPager);
    adapter = new MyPagerAdapter();     
    pager.setAdapter(adapter);
}
public class MyPagerAdapter extends PagerAdapter {

        @Override 
        public Object instantiateItem(View collection,int position) {

            Log.d("Pos",""+position);
            //PagerView = new View(collection.getContext());
            LayoutInflater inflater = (LayoutInflater) collection.getContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            PagerView = inflater.inflate(R.layout.newmainviewpager, null, false);
            lvMenu=(ListView)PagerView.findViewById(R.id.lvMenuItem);
            imgMainItem=(ImageView)PagerView.findViewById(R.id.imgDisplay);
            addMenuItemAdapter.clear();
            addMenuItemAdapter.notifyDataSetChanged();
            addMenuItemAdapter.notifyDataSetInvalidated();
            String str[][] = datasource.GetSubMenuDetailsFromMenuId(MenuIdlst
                    .get(position).trim());
            Log.d("Str", "" + str.length);
            SubMnuIdlst.clear();
            SubMnuNamelst.clear();
            ArabicSubMnulst.clear();
            TypeIdlst.clear();
            TypeNamelst.clear();
            for (int i = 0; i < str.length; i++) {

                SubMnuIdlst.add(""+str[i][0]);
                SubMnuNamelst.add(""+str[i][2]);
                ArabicSubMnulst.add(""+str[i][3]);
                Log.d("SubMenuId",""+str[i][0]);
                Log.d("SubMenuName",""+str[i][2]);
                Log.d("SubMenuNameArabicMenu",""+str[i][3]);
            }
            String [][]TypeDetails=datasource.GetTypeDetailsFromMenuId(MenuIdlst.get(position));
            for (int i = 0; i < TypeDetails.length; i++) {
                TypeIdlst.add(TypeDetails[i][0]);
                TypeNamelst.add(TypeDetails[i][3]);
                Log.d("TypeId",""+TypeDetails[i][0]);
                Log.d("TypeName",""+TypeDetails[i][3]);

            }

            for(int i=0;i<SubMnuIdlst.size();i++)
            {
                //Pricelst.clear();
                for(int j=0;j<TypeIdlst.size();j++)
                {
                    String Price=datasource.getPriceFromSubMenuIdAndTypeId(TypeIdlst.get(j),SubMnuIdlst.get(i));
                    //Pricelst.add(Price);      
                    Log.d("Adaper",MenuIdlst.get(i)+","+SubMnuIdlst.get(i)+","+SubMnuNamelst.get(i)+","+
                            TypeIdlst.get(j)+","+TypeNamelst.get(j)+","+Price);
                    addMenuItemAdapter.add(MenuIdlst.get(i)+","+SubMnuIdlst.get(i)+","+SubMnuNamelst.get(i)+","+
                                        TypeIdlst.get(j)+","+TypeNamelst.get(j)+","+Price);
                }
            }

            byte[] photo =datasource.getImagePathFromSubMenuId(SubMnuIdlst.get(position));
            ByteArrayInputStream imageStream = new ByteArrayInputStream(photo);
            Bitmap theImage= BitmapFactory.decodeStream(imageStream);
            Bitmap bitmapScaled = Bitmap.createScaledBitmap(theImage, 100,80, true);
            Drawable drawable = new BitmapDrawable(bitmapScaled);
            imgMainItem.setBackgroundDrawable(drawable);

            lvMenu.setAdapter(addMenuItemAdapter);

            ((ViewPager) collection).addView(PagerView, 0);
            return PagerView;

        }

        @Override
        public void destroyItem(ViewGroup collection, int position, Object view) {
                ((ViewPager) view).removeView((View) view);
        }


/**
 * Determines whether a page View is associated with a specific key object
 * as returned by instantiateItem(ViewGroup, int). This method is required
 * for a PagerAdapter to function properly.
 * @param view Page View to check for association with object
 * @param object Object to check for association with view
 * @return
 */
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == ((View) object);
        }


    /**
     * Called when the a change in the shown pages has been completed.  At this
     * point you must ensure that all of the pages have actually been added or
     * removed from the container as appropriate.
     * @param arg0 The containing View which is displaying this adapter's
     * page views.
     */
        @Override
        public void finishUpdate(ViewGroup arg0) {}


        @Override
        public void restoreState(Parcelable arg0, ClassLoader arg1) {}

        @Override
        public Parcelable saveState() {
                return null;
        }

        @Override
        public void startUpdate(ViewGroup arg0) {}
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return  MenuIdlst.size();
        }

    }
hemant
  • 564
  • 2
  • 13
  • 37

3 Answers3

3

It is the behavior to call it twice as view pages make its next view and store it for fast switching from current to next, basically it makes its left and right element for current view so that you can scroll page in any direction, at start page as there is no left page that's why it is called twice only. You can also change the no of views you want to create and hold for situation but in general and I think minimal(not sure but practically faced some times) is 3

Akhil Dad
  • 1,804
  • 22
  • 35
  • Thats the real reason here. I hade a PageAdapter which tried to save current pos to get resource from selection. Which was bad idea, because the ViewPager always caches the next view in advance. That is my prove of this. – Rene M. Apr 02 '15 at 12:55
  • @Erum You cannot change this behaviour, but you can call methods of that specific fragments in onPageChangeListner of ViewPager as you know which fragment is present in which position. – Akhil Dad Jun 20 '15 at 08:20
1

Could it be that your viewpager is nested inside a view group which depends on other views (e.g. LinearLayout with layout_weight set or a RelativeLayout with references to other views in order to calculate its height and/or width)? If so this could be due to multiple layout requests of the parent view since it depends on other views. If this is the cause than try to optimize your layout.

androidCoder
  • 202
  • 3
  • 5
  • 2
    That is not correct! The ViewPager always calls the Adapter twice on init. For position 0 and 1. To cache next view and to perform smooth transitions. When paging you will see that the adapter always gets called with next index to current position. – Rene M. Apr 02 '15 at 12:58
  • 1
    We do not know if "called twice" in the question means called with 0 and 1, then it is normal ViewPager behaviour, or twice with 0, then it could be a layout problem as this answer suggests. – brillenheini Nov 08 '15 at 10:47
0

Other way to fix this is overriding the getCount() method defining the number of elements to load inside the pager.

 @Override
    public int getCount() {
       return NUMBER_OF_PAGES;
   }
Jorgesys
  • 124,308
  • 23
  • 334
  • 268