[英]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);
如果GridView
在Fragment
的布局中,請通過getView().findViewById...
對其進行訪問。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.