android - Viewpager एडाप्टर getItem हमेशा सूचकांक 0 और 1 के लिए कहा जाता है




android-viewpager position (3)

हां, यह ViewPager का सामान्य व्यवहार है, क्योंकि यह हमेशा उन चित्रों को रेंडर करके उपयोगकर्ता के आगे रहने का प्रयास करेगा जो ड्राइंग क्षेत्र से सीमित होते हैं। मैं व्यक्तिगत रूप से एक कस्टम व्यूपैगर बनाने की अनुशंसा नहीं करता क्योंकि आप वास्तव में कार्यप्रणाली को तोड़ना सुनिश्चित करते हैं जब तक कि आप वास्तव में नहीं जानते कि आप क्या कर रहे हैं आपके एडेप्टर वर्ग को ऐसा कुछ दिखना चाहिए:

public class YourCustomPagerAdapter extends FragmentStatePagerAdapter {
    private List<Fragment> fragmentList = new ArrayList<>();
    private List<String> titleList = new ArrayList<>();

    public WizardPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    public void addFragment(Fragment fragment, String title) {
        fragmentList.add(fragment);
        titleList.add(title);
    }

    @Override
    public Fragment getItem(int position) {
        return fragmentList.get(position);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        super.getPageTitle(position);
        return titleList.get(position);
    }

    @Override
    public int getCount() {
        return fragmentList.size();
    }
}

और आपको अपने टुकड़े को इस तरह जोड़ना चाहिए:

 @Override
 public void onCreate(Bundle savedInstanceState) {
     ...
     YourCustomPagerAdapter adapter = new YourCustomPagerAdapter (getSupportFragmentManager());
     adapter.addFragment(FragmentOne.newInstance(), "Frag 1");
     adapter.addFragment(FragmentTwo.newInstance(), "Frag 2");
     viewPager.setAdapter(adapter);
     ...
 }

मैं बस सोच रहा था कि क्या यह getItem() और उसके एडैप्टर का सामान्य व्यवहार है, सूचकांक 0 और 1 के लिए हमेशा getItem() विधि को कॉल करने के लिए, भले ही मैंने तुरंत एक वर्तमान स्थिति निर्धारित की हो।

यहां मेरा कोड है:

mNewsPagerAdapter = new NewsDetailPagerAdapter(getChildFragmentManager());
mNewsPagerAdapter.updateNewsList(news);

mViewPager = (ViewPager) mView.findViewById(R.id.horizontal_view_pager);
mViewPager.setPageMargin(2);
mViewPager.setPageMarginDrawable(R.color.black);

mViewPager.setAdapter(mNewsPagerAdapter);
mViewPager.setCurrentItem(mCurrentPositionPager, false);

अगर मैं अपने सिंहावलोकन गतिविधि से इस getItem() साथ मेरी विस्तार गतिविधि पर स्विच करता हूं, तो एडाप्टर हमेशा स्थिति 0 और 1 के लिए getItem() विधि को mOriginalPosition और इसके बाद mOriginalPosition और उसके पड़ोसियों की स्थिति के लिए getItem() विधि। मैं सोच रहा था कि यह सही व्यवहार है या अगर मुझे इसे सही तरीके से लागू करने के लिए कुछ याद आ गया है। आपकी सहायता के लिए धन्यवाद :)

संपादित करें: मेरे एडाप्टर कोड को जोड़ा गया

public class NewsDetailPagerAdapter extends FragmentStatePagerAdapter {

private SparseArray<Fragment> mPageReferenceMap = new SparseArray<Fragment>();

private ArrayList<News> mNewsList;

public NewsDetailPagerAdapter(FragmentManager fm) {
    super(fm);
}

/**
 * Setzt die neuen News.
 **/
public void updateNewsList(ArrayList<News> list) {
    mNewsList = list;
}

@Override
public Fragment getItem(int position) {
    Log.d("debug", "getItem position:" + position);
    News newsItem = mNewsList.get(position);


    NavigationFragment fragment = new NavigationFragment();

    mPageReferenceMap.put(position, fragment);

    return fragment;
}


@Override
public int getCount() {
    return mNewsList.size();
}

@Override
public int getItemPosition(Object object) {
    return POSITION_NONE;
}

public Fragment getFragment(int position) {
    return mPageReferenceMap.get(position);
}

}


मुझे लगता है कि त्रुटि एडाप्टर है:

   /**
     * Setzt die neuen News.
     **/
    public void updateNewsList(ArrayList<News> list) {
        //mNewsList = list;
        mNewsList.clear();
        mNewsList.addAll(list);
        /**
         * Notifies the attached observers that the underlying data has been changed
         * and any View reflecting the data set should refresh itself.
         */
        this.notifyDataSetChanged();
    }

त्रुटि कारण: यह सूची उस एडेप्टर के लिए भिन्न इकाई है


वास्तव में यह सामान्य शैली है वास्तव में, जैसा कि आप एडप्टर के साथ ViewPager को संबद्ध करते हैं, एडैप्टर पहले दृश्यमान लेआउट (इंडेक्स 0) को अगले एक (सूचकांक 1) समाप्त करता है। यह "setAdapter" में डिफ़ॉल्ट रूप से किया जाता है उसके बाद, जब आप एक अलग स्थिति सेट करते हैं, तो एडैप्टर चयनित सूचकांक के टुकड़े को शुरु करेगा, पिछले एक और अगले एक।

यह सामान्य ViewPager सेट एडेप्टर कोड है:

public void setAdapter(PagerAdapter adapter) {
    if (mAdapter != null) {
        mAdapter.setViewPagerObserver(null);
        mAdapter.startUpdate(this);
        for (int i = 0; i < mItems.size(); i++) {
            final ItemInfo ii = mItems.get(i);
            mAdapter.destroyItem(this, ii.position, ii.object);
        }
        mAdapter.finishUpdate(this);
        mItems.clear();
        removeNonDecorViews();
        mCurItem = 0;
        scrollTo(0, 0);
    }

    final PagerAdapter oldAdapter = mAdapter;
    mAdapter = adapter;
    mExpectedAdapterCount = 0;

    if (mAdapter != null) {
        if (mObserver == null) {
            mObserver = new PagerObserver();
        }
        mAdapter.setViewPagerObserver(mObserver);
        mPopulatePending = false;
        final boolean wasFirstLayout = mFirstLayout;
        mFirstLayout = true;
        mExpectedAdapterCount = mAdapter.getCount();
        if (mRestoredCurItem >= 0) {
            mAdapter.restoreState(mRestoredAdapterState, mRestoredClassLoader);
            setCurrentItemInternal(mRestoredCurItem, false, true);
            mRestoredCurItem = -1;
            mRestoredAdapterState = null;
            mRestoredClassLoader = null;
        } else if (!wasFirstLayout) {
            populate();
        } else {
            requestLayout();
        }
    }

    if (mAdapterChangeListener != null && oldAdapter != adapter) {
        mAdapterChangeListener.onAdapterChanged(oldAdapter, adapter);
    }
}

ViewPager व्यवहार बदलने के लिए, आप क्लासिक दृश्यपेज सेट अप एडाप्टर विधि को ओवरराइड कर सकते हैं और इच्छित स्थिति में mCurrItem सेट कर सकते हैं।

मुझे उम्मीद है कि इसमें मदद मिलेगी

संपादित करें:

विभिन्न परीक्षणों के बाद, हमें एक समाधान मिला

ViewPager लेआउट दृश्यमान बनने के बाद ViewPager एडाप्टर सेट किया गया है, तो आइटम 0 और 1 लोड होते हैं। यदि आप इस व्यवहार से बचने के लिए चाहते हैं, लेकिन लेआउट बनने से पहले आप अडैप्टर सेट नहीं कर सकते (क्योंकि आप डेटा की प्रतीक्षा कर रहे हैं), आप इस समाधान का उपयोग कर सकते हैं:

1) सेट करने के लिए शुरू में ViewPager दृश्यता सेट करें

2) आप सभी डेटा प्राप्त करने के बाद, आप एडाप्टर अपडेट करते हैं और आप वर्तमान आइटम मान सेट करते हैं

3) अंत में आप दृश्यपैर दृश्यता दृश्यमान बनाते हैं

यहां आप एक उदाहरण पा सकते हैं:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.detail_overview_fragment, container, false);

    final int position = getArguments().getInt("position");
    final ViewPager viewPager = (ViewPager) v.findViewById(R.id.viewpager);
    viewPager.setVisibility(View.GONE);

    Handler handler = new Handler();
    handler.postDelayed(new Runnable() {
        @Override
        public void run() {
            viewPager.setAdapter(new PagerAdapter(getChildFragmentManager()));
            viewPager.setCurrentItem(position);
            viewPager.setVisibility(View.VISIBLE);

        }
    },5000);

    return v;
}




adapter