始终为索引0和1调用Viewpager Adapter getItem

jen*_*ymo 9 android position adapter android-viewpager

我只是想知道它是否正常行为viewpager及其适配器总是调用getItem()索引0和1 的方法,即使我立即设置当前位置.

这是我的代码:

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);
Run Code Online (Sandbox Code Playgroud)

如果我从概览活动切换到我的详细活动viewpager,则适配器始终调用getItem()位置0和1 的方法,然后调用getItem()位置mOriginalPosition及其邻居的方法.我想知道这是否是正确的行为,或者我错过了以正确的方式实现它的东西.谢谢你的帮助 :)

编辑:添加了我的适配器代码

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);
}
Run Code Online (Sandbox Code Playgroud)

}

Fed*_*ini 1

其实这是正常的行为。事实上,只要您将 ViewPager 与适配器关联起来,适配器就会创建第一个可见布局(索引 0)和下一个可见布局(索引 1)。默认情况下,这是在“setAdapter”中完成的。然后,当您设置不同的位置时,适配器将在所选索引处实例化片段,前一个和下一个。

这是通常的 ViewPager setAdapter 代码:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

为了更改 ViewPager 行为,您可以扩展经典 ViewPager 并重写 setAdapter 方法并将 mCurrItem 设置到所需位置。

我希望它有帮助

编辑:

经过不同的测试,我们找到了解决方案。

如果在 ViewPager 布局变得可见后设置 ViewPager 适配器,则加载项目 0 和 1。如果您想避免这种行为,但无法在布局可见之前设置适配器(因为您正在等待数据),则可以使用以下解决方法:

1) 将 ViewPager 可见性初始设置为 GONE

2)收到所有数据后,更新适配器并设置当前项目值

3)最后将ViewPager可见性设置为VISIBLE

您可以在这里找到一个示例:

@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;
}
Run Code Online (Sandbox Code Playgroud)