Фрагменты Android Viewpager.setCurrentitem() и FragmentPagerAdapter instanceiateItem() инициализируют несоответствие

У меня проблема с FragmentPagerAdapter, я установил фрагменты в viewpager через FragmentPagerAdapter, мне нужно отображать viewpager динамически, у меня есть данные listview, которые мне нужно показать в viewpager, когда я нажимаю на listview, я должен загрузить точную позицию в viewpager, поэтому я просто установил общий размер элемента для отображения в FragmentPagerAdapter, но проблема в том, что когда я выбираю позицию viewpager через mPager.setCurrentItem(listposition), он показывает правильную позицию viewpager, но данные загружаются в неправильное место, они загружаются в следующем фрагменте в позиции viewpager,после некоторого отслеживания в FragmentPagerAdapter, я показываю, что метод instanceItem инициализирует один фрагмент заранее, например, я устанавливаю currentitem (из listview) viewpager 2, а затем метод instanceiateItem инициализирует фрагмент с 0 по 3, я думаю, что причина загрузка данных в 3-м фрагменте, я также много пробовал с FragmentStatePagerAdapter, но безуспешно, пожалуйста, помогите мне, заранее спасибо.

Класс основной активности (Fragmnetactivity):

 public class NewsDetail extends FragmentActivity implements OnClickListener {
    public static ViewPager mPager;
    private static int NUM_PAGES;
    private PagerAdapter mPagerAdapter;
    public static ArrayList<Integer> exist_detail = new ArrayList<Integer>();
    public static ArrayList<PageFragment> detailfragment = new ArrayList<PageFragment>();


    mPager = (ViewPager) findViewById(R.id.pager);
    mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
    mPager.setAdapter(mPagerAdapter);

    NUM_PAGES = topList.size();
    PageFragment fragment = new PageFragment();
    Bundle args = new Bundle();
    args.putInt("page", i);
    fragment.setArguments(args);
    detailfragment.add(fragment);

    mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {

        @Override
        public void onPageSelected(int arg0) {
                if (PageFragment.getInstance() != null) {
                    Log.d("LOG","PageFragment || "+ PageFragment.getInstance());
                    PageFragment.getInstance().startLoadingNews(
                            MusicList.topMusicList.get(arg0)._id);
                }
            return;
        }

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

        @Override
        public void onPageScrollStateChanged(int arg0) {}
    });
    mPagerAdapter.notifyDataSetChanged();

    mPager.setCurrentItem(listposition);// setcurrent item from here , it is selected from list. "listposition" indicate list position click



    private class ScreenSlidePagerAdapter extends FragmentPagerAdapter {

            private FragmentManager mFragmentManager;
            private FragmentTransaction mCurTransaction = null;
            private Fragment mCurrentPrimaryItem = null;
            private static final boolean DEBUG = false;

            public ScreenSlidePagerAdapter(FragmentManager fragmentManager) {
                super(fragmentManager);
                this.mFragmentManager = fragmentManager;
            }

            @Override
            public Fragment getItem(int position) {

                return detailfragment.get(position);
            }

            @Override
            public long getItemId(int position) {
                // TODO Auto-generated method stub
                return super.getItemId(position);
            }

            @Override
            public Object instantiateItem(ViewGroup container, int position) {

                Log.v("LOG", "On InstantiateItem " + position);// it indicate that this method initialize one fragment in advance.

                return super.instantiateItem(container, position);
            }

            public String makeFragmentName(int viewId, long index) {
                return "android:switcher:" + viewId + ":" + index;
            }

            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                if (mCurTransaction == null) {
                    mCurTransaction = mFragmentManager.beginTransaction();
                }
                if (DEBUG)
                    Log.e("LOG", "Detaching item #" + position + ": f=" + object
                            + " v=" + ((Fragment) object).getView());
                mCurTransaction.detach((Fragment) object);
            }

            @Override
            public void restoreState(Parcelable state, ClassLoader loader) {
            }

            @Override
            public int getCount() {
                return NUM_PAGES;
            }
        }
        }

Фрагмент страницы

       public class PageFragment extends Fragment implements OnClickListener {

            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                mPageNumber = getArguments().getInt(ARG_PAGE);
                mDetailPageFragment = this;
            }

            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container,
                    Bundle savedInstanceState) {
                // Inflate the layout containing a title and body text.
                rootView = (ViewGroup) inflater.inflate(R.layout.newsdetail, container,
                        false);
                //init();
                return rootView;
            }
            public void startLoadingNews(String _id) {

                if (NetworkUtil.cheackNetwork(mActivity)) {
                    executeTask(_id);
                } else {
                    showRetryCancelDialog();
                }
             }
            }

person Mayur Raval    schedule 01.11.2014    source источник


Ответы (1)


Я вижу две проблемы в коде, который вы опубликовали:

  1. Создавайте свои фрагменты только в FragmentPagerAdapter.getItem. Не создавайте их и не сохраняйте в какой-либо список или массив, пусть FragmentPagerAdapter сделает это за вас. В FragmentPagerAdapter.instantiateItem он проверяет, был ли уже создан Fragment, и если да, то возвращает его, если нет, то вызывает ваш getItem для создания фрагмента.
  2. Не используйте схему Singleton для своего фрагмента, создайте новый фрагмент с помощью конструктора или статического помощника .newInstance().
person marmor    schedule 08.07.2015