Android FragmentStatePagerAdapter-缺少视图

Android FragmentStatePagerAdapter-缺少视图,android,fragmentstatepageradapter,Android,Fragmentstatepageradapter,我已经创建了一组水平选项卡,对于每个选项卡内容,它都有一个视图寻呼机,该寻呼机反过来允许浏览视图的内容 我目前正在适配器中对这3个视图进行编码,并在调用getItem()时返回一个表示细节的新内部片段 这可以正常工作,直到我导航到另一个选项卡,当我返回中间视图时,所有选项卡都会出现这种情况 当我查看调试时,我只看到对位置0和2的getItem的调用,但始终缺少一个视图,因此,如果我滑动,我会得到另一个视图,而不是渲染视图,我只是没有布局 如果我不点击另一个标签,而是在默认的标签一中继续浏览视图,

我已经创建了一组水平选项卡,对于每个选项卡内容,它都有一个视图寻呼机,该寻呼机反过来允许浏览视图的内容

我目前正在适配器中对这3个视图进行编码,并在调用getItem()时返回一个表示细节的新内部片段

这可以正常工作,直到我导航到另一个选项卡,当我返回中间视图时,所有选项卡都会出现这种情况

当我查看调试时,我只看到对位置0和2的getItem的调用,但始终缺少一个视图,因此,如果我滑动,我会得到另一个视图,而不是渲染视图,我只是没有布局

如果我不点击另一个标签,而是在默认的标签一中继续浏览视图,那么我不会丢失一个视图,这似乎只是在我点击转到另一个标签然后再返回时。但我从未在位置1中看到视图请求,只有0或2

我的适配器是片段的一个内部类,它表示ViewPager,如下所示:

public class HomeAddressDetailFragmentStatePageAdapter extends FragmentStatePagerAdapter {

    public HomeAddressDetailFragmentStatePageAdapter(FragmentManager fragmentManager) {
        super(fragmentManager);
    }

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

    @Override
    public android.support.v4.app.Fragment getItem(int position) {
        Log.d(LOG_TAG, "requesting tab view in position: " + position);
        android.support.v4.app.Fragment fragment = null;

        fragment = new HomeAddressDetailFragment();

        return fragment;
    }
}
片段的onCreate:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View rootView = (View)inflater.inflate(R.layout.fragment_home_addresses, container, false);
    HomeAddressDetailFragmentStatePageAdapter homeAddressDetailFragmentStatePageAdapter = new HomeAddressDetailFragmentStatePageAdapter(getFragmentManager());
    homeAddressViewPager = (ViewPager)rootView.findViewById(R.id.home_addr_pager);
    homeAddressViewPager.setAdapter(homeAddressDetailFragmentStatePageAdapter);

    return rootView;
}
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
  <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/home_addr_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1">

  </android.support.v4.view.ViewPager>
</FrameLayout>    
以及此片段的xml:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View rootView = (View)inflater.inflate(R.layout.fragment_home_addresses, container, false);
    HomeAddressDetailFragmentStatePageAdapter homeAddressDetailFragmentStatePageAdapter = new HomeAddressDetailFragmentStatePageAdapter(getFragmentManager());
    homeAddressViewPager = (ViewPager)rootView.findViewById(R.id.home_addr_pager);
    homeAddressViewPager.setAdapter(homeAddressDetailFragmentStatePageAdapter);

    return rootView;
}
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
  <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/home_addr_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1">

  </android.support.v4.view.ViewPager>
</FrameLayout>    

这是默认设置FragmentStatePagerAdapter随时保存加载的两个片段

就你而言:

  • 位置0和1

  • 位置1和2
意思是位置1处的碎片总是“在那里”

您可以(因为您有3个片段)告诉您的
ViewPager
,一次加载两个以上的片段

homeAddressViewPager.setOffscreenPageLimit(2);
这样,就不会重新加载片段(默认情况下offScreenPageLimit设置为1)

setOffscreenPageLimit(整数)

设置在空闲状态下视图层次结构中当前页面两侧应保留的页数

但是。。。最好在适配器不需要时保存片段状态,并在它再次可见时重新加载(例如,使用
onSaveInstanceState

更新:

正如所讨论的,你的工作流程是这样的。您发送一个请求来获取所有地址,在ArrayList中解析它们,每个片段都应该是ArrayList中一个条目的表示

最好的方法是将解析后的ArrayList传递给适配器,并且在调用
getItem()
时,将ArrayList条目传递给捆绑包(以便可以在片段中访问它)

公共类HomeAddressDetailFragmentStatePageAdapter扩展了FragmentStatePagerAdapter{
私有ArrayList arrayListAddress;
公共HomeAddressDetailFragmentStatePageAdapter(FragmentManager FragmentManager,ArrayList ArrayList){
超级(碎片管理器);
arrayListAddress=arrayList;
}
@凌驾
public int getCount(){
返回arrayListAddress.size();
}
@凌驾
public android.support.v4.app.Fragment getItem(int位置){
Bundle=新Bundle();
bundle.putSerializable(“address”,arrayListAddress.get(position));
android.support.v4.app.Fragment Fragment=新的HomeAddressDetailFragment();
fragment.setArguments(bundle);
返回片段;
}
}

好吧,我的下一个障碍是通过网络呼叫来备份标签,以获取真正的地址,然后将其修复到这个位置,那么,我是否应该始终将上述方法设置为比我的地址数组列表中的项目数少1个?如果位置1始终存在,为什么它不呈现实际的视图布局?事实上,如果我可以要求视图寻呼机不要维护任何视图,我想这样会更好,因为每次请求视图时,我都可以从数组,然后呈现数据。这是个坏主意吗?对于n个片段,您应该保存片段状态并将其还原(例如,使用
onSaveInstanceState
)。不要设置OffscreenPagilemit为n-1,那样会很糟糕。位置1可能会呈现,但仅在您第一次创建适配器时呈现,而不是在您刷卡时呈现。如果您正在对每个片段进行网络抓取,则最好保存下载的数据,而不是在适配器重新加载您的片段时,您应该还原下载的数据,而不是再次调用网络请求(虽然这样做行得通,但我认为没有必要)