一、什么是Fragment
在应用程序中, 一个Fragment应该是一个模块化、可重用的“片段Activity”。其行为与Activity很相似,有自己对应的View,有自己的生命周期(受宿主Activity的生命周期影响)。
可以在多个Activity中包括同一个Fragment,也可以在一个Activity中包含多个Fragment。
更为重要的是,可以动态的给Activity添加、替换和移除某个Fragment。
当Activity界面中有Fragment,那么该Activity需要继承FragmentActivity。
导包:android-support-v4.jar ,可兼容低版本的安卓系统。
每个Fragment本质上都会生成一个FrameLayout根布局。(与Activity类似)
二、Fragment的加载方式
1. 定义Fragment的子类,并加载一个布局文件
public class MyFragment1 extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//加载视图:将layout布局文件转换成View对象
/**inflater.inflate 参数说明
* resource:Fragment需要加载的布局文件
* root:加载layout的父ViewGroup
* attactToRoot:false,不返回父ViewGroup
*/
View view = inflater.inflate(R.layout.fragment, container, false);
// 根据id获取布局里面的TextView
TextView text=(TextView) view.findViewById(R.id.text);
text.setText("动态加载Fragment");
//返回视图
return view;
}
}
2. 静态加载
直接在在Activity对应的XML布局文件中添加上fragment标签
<fragment android:name="com.example.MyFragment1"
android:id="@+id/myfragment1"
android:tag="myfragment1"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:name为对应的Fragment的类名
android:id/tag可唯一标识Fragment。
(每个fragment需要一个唯一的标识,当activity重新启动时,系统需要使用这个唯一的标识去恢复这个fragment。)宿主Activity和Fragment共享控件,可以在Activity中直接findViewById来查找已添加的Fragment中的控件。
3. 动态加载
在你的activity中管理fragment ,你需要使用 FragmentManager 来使用开始事务。
//创建Fragment对象
MyFragment1 myfragment1 = new Fragment1();
//通过事务来动态处理Fragment
FragmentManager fm = this.getFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
//添加Fragment对象。tag为该该对象的标识。
transaction.add(R.id.id_content, myfragment1,"tag");
//add:将当前Fragment的布局添加id_content的布局中
//replace(R.id...,fragment):将当前Fragment的布局替代id_content的控件
//remove():将当前Fragment的布局从id_content的布局移除中
//hide() show() attach() detach()
//transaction.addToBackStack("tag");
transaction.commit(); //提交事务
BackStack —- Fragment回溯栈
如果你的多个改变放在同一个事务中,想要记录之前的Fragment,那就在commit() 之前调用了addToBackStack(String tag)方法(参数’tag’将作为本次加入BackStack的Transaction的标志),此时所有的改变都会作为一个事务增加到返回栈当中去。当按返回键之后,改变会回滚到上一次保留的状态。
可以调用popBackStack函数将Fragment弹出桟。
三、Fragment的生命周期
Fragment的生命周期和宿主Activity有关,可以通过Activity的生命周期来理解Fragment的生命周期。
四、宿主Activity向Fragment通信
//Activity中
MyFragment5 fragment5 = new MyFragment5();
Bundle bundle = new Bundle();
bundle.putString("name", "data");
//使用Fragment的setArguments方法
fragment5.setArguments(bundle);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
beginTransaction.add(R.id.layout, fragment5, "fragment5");
beginTransaction.commit();
当Activity中没有任何Fragment的引用时(例如静态加载Fragment),可以通过getFragmentManager.findFragmentByTag()或者findFragmentById()获得任何Fragment实例,然后进行操作。(每个Fragment都有一个唯一的tag或者id)
public class MyFragment5 extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.fragment2, container, false);
//在Fragment中接收。接收时可判断是否为空。
String text=getArguments().get("name");
return view;
}
}
五、Fragment向宿主Activity通信
Fragment向宿主Activity通信:可以在Fragment中声明一个接口,在接口里定义带参数(参数即我们要传过去的数据)的抽象方法,为activity创建一个回调事件。
在一个fragment中定义一个回调接口,然后activity实现此接口.当这个activity接收到这个接口的回调时,如果需要的话,你还可以共享你的数据与其他的fragment。
public class MyFragment5 extends Fragment{
private String code="Hi,Activity!";
public MyListener listener;
public interface MyListener
{
public void hi(String code);
}
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
listener=(MyListener) activity;
super.onAttach(activity);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.fragment2, container, false);
listener.hi(code); //让Activity调用其自身方法
return view;
}
}
public class MainActivity extends Activity implements MyFragment5.MyListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main4);
}
@Override
public void hi(String code) {
Toast.makeText(MainActivity.this, "已成功接收到" + code + ",客气了!",
Toast.LENGTH_SHORT).show();
}
}