Fragment中的ViewPager--使用Nested Fragment
目的:在Fragemnt中放入ViewPager,可在功能表中切換fragment頁面,而子Fragment中又有可滑動的pager
首先有幾個需要注意的地方
1.用來實做ViewPager的Fragment的類別引用android.app.Fragment,而非support.v4.app.Fragment,否則無法使用巢狀fragment
2.在API 23以前使用Fragment中類別OnAttach(Activity activity),API 23以後才用OnAttach(Context Context)
結構圖
先提供Adapter每一個子頁面的資料,viewpager就可決定要顯是哪一個頁面。 而viewpager本身也是放在一個fragment中,所以UI可以更靈活操作什麼時候要顯示這個畫面 |
首先需要新增一個放置ViewPager的父Fragment使用List集合加入每一個頁面代表的Fragment 宣告一個自訂的PagerAdapter ,傳入FragmentManger和List建構物件 注意:因為提供page的所代表的Fragment是子Fragment所以提供的Manager要用getChildFragmentManager()
public class fragment_slide extends Fragment {
private ViewPager mViewPager;
private View view;
private android.support.design.widget.TabLayout mTabs;
Activity activity;
@Override public void onActivityCreated(Bundle savedInstantState) {
super.onActivityCreated(savedInstantState);
initialTabs();
initialViewPager();
}
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstantState)
{
view = inflater.inflate(R.layout.slide_layout,container,false);
return view;
}
@Override public void onAttach(Activity activity) {
super.onAttach(activity);
Log.d("FragmentSlide", "onAttach");
this.activity = activity;
}
private void initialTabs() {
mTabs = (android.support.design.widget.TabLayout) view.findViewById(R.id.tabs);
mTabs.addTab(mTabs.newTab().setText("Tab 1"));
mTabs.addTab(mTabs.newTab().setText("Tab 2"));
mTabs.addTab(mTabs.newTab().setText("Tab 3"));
mTabs.addTab(mTabs.newTab().setText("Tab 4"));
}
private void initialViewPager() {
List<Fragment> fragments = new ArrayList<Fragment>();
fragments.add(FragmentPage.newInstance("Page1",1));
fragments.add(FragmentPage.newInstance("Page2",2));
fragments.add(FragmentPage.newInstance("Page3",3));
fragments.add(FragmentPage.newInstance("Page4",4));
PagerAdapter myPagerAdapter = new azuresky.smartdrug.Adapters.PagerAdapter(getChildFragmentManager(),fragments);
mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
mViewPager.setAdapter(myPagerAdapter);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabs));
}
}
PagerAdapter是用來提供ViewPager資料的容器,因為我們希望把page放在Fragment中,
所以這邊有兩種選擇 1.繼承FragmentPagerAdapter:適合頁面數量少的情況,因為每個 Fragment
頁面會持續的被保留在記憶體中,在頁面不可見(not visible)的情況下,view 會被銷毀,
但整個 Fragment 仍然存在。
2.繼成FragmentStatePagerAdapter:使用較多頁面,在頁面不可見(not visible)的情況下
,整個 Fragment 都會被銷毀,只保留狀態 (state),因此不會佔用大量的記憶體。
public class PagerAdapter extends FragmentStatePagerAdapter {
private List<Fragment> fragments;
public PagerAdapter(FragmentManager fm,List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
Log.d("PagerAdapter",fm.toString());
Log.d("PagerAdapter","");
}
@Override public android.app.Fragment getItem(int position) {
return fragments.get(position);
}
@Override public int getCount() {
return 4;
}
}
接著就是建立每一個頁面要放置的Fragment 使用newInstance這個方法來提供Fragment物件實例,透過setArgument來設定bundle給Fragment
1.在 onCreate() 中可用getArguments()來取得bundle
2.在 onCreateView() 中指定layout
3.在 onViewCreated() 中可以對view做動作
如果需要 Activity 的資源,則在 onActivityCreated() 方法中取用。
使用FragmentStatePagerAdapter可以使用Log來看Fragment的生命週期,
可以發現Adapter知會預先載入當前畫面的前後一個頁面。
其他已經create的view都會onDestroyView->onDestroy->onDetach
public class FragmentPage extends Fragment{
private static final String TITLE = "TITLE";
private static final String RESID= "RESID";
private String title;
public static final FragmentPage newInstance(String title, int resId){
FragmentPage fg = new FragmentPage();
Bundle bd = new Bundle();
bd.putString(TITLE,title);
bd.putInt(RESID, resId);
fg.setArguments(bd);
return fg;
}
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragmentpage,container,false);
return view;
}
@Override public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
TextView text1 = (TextView)view.findViewById(R.id.text1);
text1.setText(getArguments().getString(TITLE));
}
執行結果
留言
張貼留言