FragmentPagerAdapter的getItem方法位置错误

8

我遇到了一个关于FragmentPagerAdapter的奇怪问题。

MainActivity.java

@SuppressLint("ValidFragment")
public class MainActivity<DashboardActivity> extends FragmentActivity implements     ActionBar.TabListener {
...
...
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    mTabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
    mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
    mViewPager = (ViewPager) findViewById(R.id.pager);
    mViewPager.setAdapter(mSectionsPagerAdapter);
    mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
        @Override
        public void onPageSelected(int position) {
            actionBar.setSelectedNavigationItem(position);
        }
    });

    actionBar.addTab(actionBar.newTab().setText(mSectionsPagerAdapter.getPageTitle(0)).setTabListener(this).setIcon(R.drawable.rating_good));
    actionBar.addTab(actionBar.newTab().setText(mSectionsPagerAdapter.getPageTitle(1)).setTabListener(this).setIcon(R.drawable.action_search));
    actionBar.addTab(actionBar.newTab().setText(mSectionsPagerAdapter.getPageTitle(2)).setTabListener(this).setIcon(R.drawable.action_search));
}
...
public class SectionsPagerAdapter extends FragmentPagerAdapter {
    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }
    public Fragment getItem(int position) {
        Fragment fragment = null; 
        switch(position) {
            case 0:
                fragment = new Fragment0();  
            break;
            case 1:
                fragment = new Fragment1();  
            break;
            case 2:
                fragment = new Fragment2();  
            break;
        }
        return fragment;
    }
    @Override
    public int getCount() {
        return 3;
    }
    /*
     * Title
     */
    @Override
    public CharSequence getPageTitle(int position) {
        Locale l = Locale.getDefault();
        switch (position) {
        case 0:
            return getString(R.string.title_section0).toUpperCase(l);
        case 1:
            return getString(R.string.title_section1).toUpperCase(l);
        case 2:
            return getString(R.string.title_section2).toUpperCase(l);
        }
        return null;
    }
}

当我尝试在3个选项卡之间切换时,public Fragment getItem(int position)返回错误的位置。当我创建只有2个选项卡的应用程序时,一切正常。添加超过2个选项卡会导致奇怪的问题。 从0切换到1位置-正常工作,从1切换到0位置-正常工作,从1切换到2位置-正常工作,但是,当我尝试从2返回到1位置时,public Fragment getItem(int position)-int位置返回“0”而不是“1”。 有人能帮我解决这个问题吗?


这似乎是一个关键问题,有人有“正确的解决方案”吗? - Snake
4个回答

9

好的,我找到了解决方案。 首先,getItem "int position"并没有指示当前显示的片段。 如果要显示3个或更多的选项卡,而不卸载第一个片段,则必须添加此行:

mViewPager.setOffscreenPageLimit(3);

故事结束了...

1
这是一个非常糟糕的建议。当碎片没有使用时,您不应该让它们保持活动状态,这就是为什么Android会调用finish()方法。通过添加以下代码:mViewPager.setOffscreenPageLimit(count); 您要求Android不清除这些未使用的碎片,请想象一下当您的碎片有大量图像时会发生什么。 - DJphy
@user2536592,你解决了我面临的同样问题吗?我的public Fragment getItem(int i)被调用了两次,导致位置错误。我有5个选项卡和5个片段。如果(i>0){i = i-1;}可以解决问题,但是问题在于最后一个标签或碎片没有被调用,因为position = position -1。mViewPager.setOffscreenPageLimit(4); 对我不起作用。 - Mushtaq Rahim

3
你只需要:
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

    }

    @Override
    public void onPageSelected(int position) {
        Log.d("test", "position = " + position);
    }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
});

onPageSelected 中的 position 是您想要的。


2

我曾经遇到过同样的问题,我在每个选项卡内使用了片段;因此,不是使用

mViewPager.setAdapter(new MainTabs(getFragmentManager()));

使用这个:

mViewPager.setAdapter(new MainTabs(getChildFragmentManager()));

在minSDK 14上有没有办法使用getChildFragmentManager()? - Emerick
无法在支持库中获取getChildFragmentManager(除非您是最前沿的..) - Oliver Dixon

1
如果有其他人遇到同样的问题,我通过不使用给定的position来解决它。相反,我使用getSupportFragmentManager获取Fragment列表,循环检查当前Fragment是否是我所需的Fragment实例。请注意保留HTML标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接