Fragment探究
先掉一下书袋:之前做底部栏菜单这样的功能,由于项目是迭代开发,工程结构基本已经固定,在不考虑重构的前提下,采用简单的实现,将其他菜单选项切换对应的布局全部嵌入主布局中。通过控制可见性(设置Gone、Visiable)实现菜单切换。
但是这个有很大的弊端:
- 主布局嵌套过多,内容加载速度延缓
- 网络集中请求,需要的当前数据加载缓慢
- 另外,臃肿的Activity逻辑复杂,维护困难
需要寻求另外一个解决方案,需要满足可控的状态回调和状态保持。经过对比TableHost、ActivityGroup、Fragment,最终确定使用fragment。Fragment具有和Activity同步的状态回调函数(onresume,onstop,onPause),原本在这些状态下需要处理的逻辑很容易从Activity抽到Fragment中。
抽取过程
1 继承Fragment 在onCreateView中
mainView = inflater.inflate(R.layout.layout_main, container, false);
2 在原本Activity中onCreate()中findViewById的操作之前改为mainView.findViewById
3 其他的逻辑对应的抽取。
拓展
两种不同的Adapter:FragmentStatePagerAdapter ,FragmentPagerAdapter
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pagers_fragment_main);
mAdapter = new MyAdapter(getSupportFragmentManager() );
mPager = (ViewPager)findViewById(R.id.mypagers_pager);
mPager.setAdapter(mAdapter);
}/**
- 有状态的 ,只会有前3个存在 其他销毁, 前1个, 中间, 下一个
*/
public static class MyAdapter extends FragmentStatePagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return NUM_ITEMS;
}//得到每个item
@Override
public Fragment getItem(int position) {
return ArrayFragment.newInstance(position);
}// 初始化每个页卡选项
@Override
public Object instantiateItem(ViewGroup arg0, int arg1) {
// TODO Auto-generated method stub
return super.instantiateItem(arg0, arg1);
}@Override
public void destroyItem(ViewGroup container, int position, Object object) {
System.out.println( “position Destory” + position);
super.destroyItem(container, position, object);
}}
/**
* 无状态的 会全部加载着, 这个适合少量的 特别多的图片啊啥的 还是用 FragmentStatePagerAdapter
* @author lilei
*/
// public static class MyAdapter extends FragmentPagerAdapter {
// public MyAdapter(FragmentManager fm ) {
// super(fm);
//
// }
//
// @Override
// public int getCount() {
// return NUM_ITEMS;
// }
//
// @Override
// public Fragment getItem(int position) {
// // 返回相应的 fragment
// return ArrayFragment.newInstance(position);
// }
//
// @Override
// public void destroyItem(ViewGroup container, int position, Object object) {
// System.out.println( “position Destory” + position);
// super.destroyItem(container, position, object);
// }
// }/** * 所有的 每个Fragment */ public static class ArrayFragment extends Fragment { int mNum; static ArrayFragment newInstance(int num) { ArrayFragment array= new ArrayFragment(); Bundle args = new Bundle(); args.putInt("num", num); array.setArguments(args); return array; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mNum = getArguments() != null ? getArguments().getInt("num") : 1; System.out.println("mNum Fragment create ="+ mNum); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { System.out.println("onCreateView = "); //在这里加载每个 fragment的显示的 View View v = null; if(mNum == 0){ v = inflater.inflate(R.layout.pagers_fragment1, container, false); ((TextView)v.findViewById(R.id.textView1)).setText(mNum+ "= mNum"); }else if(mNum == 1){ v = inflater.inflate(R.layout.pagers_fragment1, container, false); ((TextView)v.findViewById(R.id.textView1)).setText(mNum+ "= mNum"); }else if(mNum == 2){ v = inflater.inflate(R.layout.pagers_fragment1, container, false); ((TextView)v.findViewById(R.id.textView1)).setText(mNum+ "= mNum"); }else{ v = inflater.inflate(R.layout.pagers_fragment1, container, false); ((TextView)v.findViewById(R.id.textView1)).setText(mNum+ "= mNum"); } return v; } @Override public void onActivityCreated(Bundle savedInstanceState) { System.out.println("onActivityCreated = "); super.onActivityCreated(savedInstanceState); } @Override public void onDestroyView(){ System.out.println(mNum + "mNumDestory"); super.onDestroyView(); } @Override public void onDestroy(){ super.onDestroy(); } }
}
- 有状态的 ,只会有前3个存在 其他销毁, 前1个, 中间, 下一个
需要注意的地方、
Activity和Fragment之间的通信
Fragment可以通过getActivity()来获得Activity实例,进而控制Activity的对象;
Activity想要控制Fragment,可以在Fragment中声明一个接口,在Activity中实现这个接口,
在Fragment的OnAttach中将activity强转成接口对象。
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnArticleSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
}
}
生命周期
显示Fragment时(跟用户交互)要调用的核心的生命周期方法如下:
把Fragment对象跟Activity关联时,调用onAttach(Activity)方法;
Fragment对象的初始创建时,调用onCreate(Bundle)方法;
onCreateView(LayoutInflater, ViewGroup, Bundle)方法用于创建和返回跟Fragment关联的View对象;
onActivityCreate(Bundle)方法会告诉Fragment对象,它所依附的Activity对象已经完成了Activity.onCreate()方法的执行;
onStart()方法会让Fragment对象显示给用户(在包含该Fragment对象的Activity被启动后);
onResume()会让Fragment对象跟用户交互(在包含该Fragment对象的Activity被启恢复后)。
Fragment对象不再使用时,要反向回调的方法:
因为Fragment对象所依附的Activity对象被挂起,或者在Activity中正在执行一个修改Fragment对象的操作,而导致Fragment对象不再跟用户交互时,系统会调用Fragment对象的onPause()方法;
因为Fragment对象所依附的Activity对象被终止,或者再Activity中正在执行一个修改Fragment对象的操作,而导致Fragment对象不再显示给用户时,系统会调用Fragment对象的onStop()方法。
onDestroyView()方法用于清除跟Fragment中的View对象关联的资源;
Fragment对象的状态被最终清理完成之后,要调用onDestroy()方法;
在Fragment对象不再跟它依附的Activity关联的时候,onDetach()方法会立即被调用
8/31/2015 11:28:22 AM