簡體   English   中英

在片段中使用FragmentPagerAdapter

[英]Using FragmentPagerAdapter in a Fragment

我已經在一些Android代碼中做了一些重構,其中我在直接連接到Activity的視圖中使用了FragmentPagerAdapter和ViewPager。 然后,作為重構的一部分,將FragmentPageAdapter從“活動”移到“分離的片段”(現在是該活動的子對象)中。

此更改進行得並不順利。 例如,在更改方向后,緩存的標簽消失了。 NullPointerExceptions遍歷了我的Fragment子類中的所有位置,因為findViewById無法找到它的View組件(看起來像Fragments的View層次結構在旋轉更改后以某種方式被破壞了)。

我正在使用最新版本的Android支持庫。

關於出什么問題的任何想法?

編輯:

我當前的實現:

public class TabsPageAdapter extends FragmentPagerAdapter {

    ...

    @Override
    public Fragment getItem(int index) {
        // tabs = list of Fragment instances created in contructor of pager adapter - bad habbit?
        return tabs.get(index).getTabFragment();
    }

    ...

}


public class StatsFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.stats_view, container, false);

        TabsPageAdapter adapter = new TabsPageAdapter(getActivity().getSupportFragmentManager(), getActivity());
        ViewPager viewPager = (ViewPager) root.findViewById(R.id.tabPager);
        viewPager.setAdapter(adapter);
        viewPager.setOffscreenPageLimit(3);
        TabPageIndicator pageIndicator = (TabPageIndicator) root.findViewById(R.id.tabIndicator);
        pageIndicator.setViewPager(viewPager);  
        return root;
    }
}


public class MedalsTab extends Fragment {

    private MedalAdapter adapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.medals, container, false);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState){
        super.onActivityCreated(savedInstanceState);
        this.adapter = new MedalAdapter();
        GridView gridView = (GridView) getActivity().findViewById(R.id.grdMedals);
        // Nullpointerexception is thrown here
        gridView.setAdapter(adapter);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        //first saving my state, so the bundle wont be empty.
        //http://code.google.com/p/android/issues/detail?id=19917
        outState.putString("WORKAROUND_FOR_BUG_19917_KEY", "WORKAROUND_FOR_BUG_19917_VALUE");
        super.onSaveInstanceState(outState);
    }

    ...

}

在尋呼機適配器的選項卡中滑動時,我也遇到了此異常。

E/AndroidRuntime(28706): java.lang.NullPointerException
E/AndroidRuntime(28706):    at android.support.v4.app.Fragment.instantiate(Fragment.java:391)

這是我解決問題的方法:

我更改了getItem方法以構造並返回一個新實例(感謝Luksprog):

    @Override
    public Fragment getItem(int index) {
        return tabs.get(index).constructFragment();
    }

由於ViewPager駐留在片段中,我們需要使用getChildFragmentManger()返回的FragmentManager而不是getActivity().getFragmentManager()來創建片段:

TabsPageAdapter adapter = new TabsPageAdapter(getChildFragmentManager(), getActivity());

// tabs =在尋呼機適配器的構造器中創建的Fragment實例列表-壞習慣?

是的,這很糟糕,很可能是輪換后您出現問題的根源。 當需要將片段顯示在頁面中時, ViewPager將使用getItem方法獲取片段。 旋轉后, ViewPager將檢查其狀態,並查看其先前有多少片段,並在沒有getItem方法的情況下手動還原它們。 如果您在此機制之外保留片段,則需要更改適配器,使其僅使用列表中的片段( getItem()還不夠),或者更新片段列表以僅引用由ViewPager創建或重新創建的片段。 您很可能不這樣做,並且在輪換之后,您嘗試訪問列表片段,並假設它們是ViewPager ,它將拋出NullPointerException動作。

GridView gridView =(GridView)getActivity()。findViewById(R.id.grdMedals);

如果GridViewFragment的布局中,請通過getView().findViewById...對其進行訪問。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM