显示的ViewPager第一个片段始终与FragmentStatePager错误

时间:2014-12-27 22:47:46

标签: android tabs android-viewpager fragmentstatepageradapter

我正在尝试使用与PlayStore 5.1.x相同的view pager + tabs设计。 这是我的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center_vertical|center_horizontal"
    android:gravity="center_vertical|center_horizontal"
    android:orientation="vertical">

    <com.astuetz.PagerSlidingTabStrip
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@drawable/background_tabs" />

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

我的适配器:

public class MainPagerAdapter extends FragmentStatePagerAdapter {

    private ArrayList<FakeFragment> fragments;

    public MainPagerAdapter(FragmentManager fm) {
        super(fm);
        // TODO Auto-generated constructor stub
        fragments = new ArrayList<FakeFragment>();
    }

    @Override
    public Fragment getItem(int position) {
        // TODO Auto-generated method stub      
        if(position < getCount()) {
            FakeFragment fragment = FakeFragment.newInstance(position);
            fragments.add(fragment);
        }
        return fragments.get(position);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return Category.values().length;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        // TODO Auto-generated method stub
        return Category.values()[position].getTitle();
    }

    @Override
    public int getItemPosition(Object object) {
        // TODO Auto-generated method stub
        return POSITION_NONE;
    }
}

我的标签和寻呼机正确显示!但我注意到视图寻呼机中显示的第一个片段始终与第二个片段相同。然后当我滑动一次,两次并向后滑动到第一页时,我发现现在显示了正确的片段!

我无法理解为什么会出现这种情况,请我解释一下。

解决方案

问题是由于我的FakeFragment.newInstance()方法定义。

private static int position;

public static FakeFragment newInstance(int position) {
    // TODO Auto-generated method stub
    FakeFragment.position = position;
    return new FakeFragment();
}

我使用setArguments(args)对我的FakeFragment实例进行了更改,然后使用onCreate方法检索它。现在一切都很好!

有人可以解释我为什么吗?

我认为,通过这种方式,位置的价值将依赖于片段的生命周期,因此将始终是预期的位置,对吧?

2 个答案:

答案 0 :(得分:6)

1)如果不处理,请不要实施getItemPosition(Object)。您不需要实现它,并且可能通过错误地实现它来破坏其他功能。

2)getItem(int)的要点是返回一个新片段。抛弃片段数组,因为没有意义。

3)创建adpater类static(它提升可重用性,适配器不应该依赖于父类来获取其数据集,对吗?)并将Category s作为构造函数参数传递。将其存储在变量中,并根据此数据集创建新的片段。您可能还希望将Category[position]作为参数传递给片段构造函数,而不仅仅是position

答案 1 :(得分:3)

getItem()实施是问题所在。

@Override
public Fragment getItem(final int position) {
    return FakeFragment.newInstance(position);
}

您永远不应该更改此get方法中的数据:不要在其中调用add()。我怀疑Adapter此时会知道你添加了一个元素。