Класс PagerAdapter вызывается несколько раз

Я работаю над приложением, в котором есть представление ViewPager, Я создал PagerAdapter, который имеет представление, instantiateItem () метод PagerAdapter вызывается дважды в create () я не знаю, почему, Может ли кто-нибудь помочь мне в этом?

вот мой код

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

    }

пожалуйста, помогите

5 ответов


если вы решили использовать фрагменты, не реализуйте PagerAdapter. Вместо этого, расширьте FragmentPagerAdapter или 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 ...); 
    }
}

тогда в вашей деятельности:

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

чтобы получить больше информации о том, как использовать фрагменты и 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


ViewPager по умолчанию загружает одну страницу вперед / перед текущей страницей (если таковые имеются). Вы не сказали, что его вызывают на ту же или другую должность.


ViewPager.setOffscreenpageLimit (int) минимальное значение 1. Вы можете видеть это из исходный код для 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();
        }
    }

вы должны увидеть предупреждение в Logcat, если вы попытаетесь установить его в ноль.

нижний предел равен 1 по очень веской причине. Соседняя страница должна быть уже загружена при прокрутке пейджера-иначе вы ничего не увидите на следующей странице. Если вам удастся принудительно ограничить экранную страницу до нуля, вероятно, вы просто увидите черную пустую страницу при прокрутке с первой страницы на вторую. Если у вас есть конкретная проблема с созданием первой и второй страниц в начале, попробуйте настроить таргетинг и исправить это.


используйте фрагменты для каждого представления в пейджере.

напишите приведенный ниже код в onCreate() метод 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);

определение фрагмента образца:

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;
}

Я следую этому методу всякий раз, когда мне нужно использовать ViewPager. Надеюсь, это поможет. Я не мог понять, почему ваш экземпляр метода вызывается дважды из предоставленной Вами информации.


есть изменение, которое необходимо для метода isViewFromObject (). Это очень важно, и в его документации сказано, что " этот метод необходим для правильной работы PagerAdapter."

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

вы можете ознакомиться здесь.