简介
- Fragment可以看作Activity的一部分,可以理解为模块化的Activity
- 是依附于Activity存在的,使用的时候需要添加到Activity中
- Fragment的生命周期是完全取决于当时依附的Activity的生命周期,如果Activity处于暂停,那么依附在Activity上的Fragment都要处于暂停状态。
- Fragment有自己独立的生命周期方法,受Activity影响。
Fragment的生命周期
- onAttach: 当Activity与Fragment进行关联的时候调用。
- onCreate
- onCreateView:Fragment的布局初始化是在这个方法中进行的。
- onActivityCreated:当Activity的onCreate方法执行完毕后,Fragment会执行这个方法。
- onStart:
- onResume:
- onPause
- onStop
- onDestroyView
- onDestroy
- onDetach : Activity与Fragment不再关联的时候调用。
Fragment的加载方式
- 布局中添加Fragment
- 直接在Activity布局中加入fragment标签将Fragment与Activity绑定
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".MainActivity">
<fragment
android:id="@+id/mFragmentOne"
android:name="wanandroidqi.dashingqi.com.fragmentdemoproject.OneFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<fragment
android:id="@+id/mFragmentSecond"
android:name="wanandroidqi.dashingqi.com.fragmentdemoproject.SecondFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
- 注意两点
- fragment标签中需要在使用name(或者是tag,或者为父布局指明一个ID)属性来指明是那个fragment
-
需要为每个fragment指明一个唯一的id,不指明id的话会出现下面的错误信息。
xml_add_fragment_error.jpg
报错信息指明你可以为每个Fragment指明一个Id,或者Tag,或者直接为父布局指明一个id。这样就能避免出现这个问题了。
- 在Activity.java 里面动态加载Fragment
- 通过FragmentManager来开启事务,操作事务,最终提交事物。
// 1. 在xml文件布局中写一个占位符的布局,用来动态加载Fragment <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/mFragment" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <Button android:id="@+id/btnLoadFragment" android:layout_width="match_parent" android:layout_height="wrap_content" /> <FrameLayout android:id="@+id/mContainerView" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> // 2. 新建一个Fragment // 3. 开启事务动态加载Fragment private void loadFragment(){ //获取到FragmentManager的实例 FragmentManager fragmentManager = getSupportFragmentManager(); //开启事物 FragmentTransaction transaction = fragmentManager.beginTransaction(); //将Fragment添加到FrameLayout布局中。 transaction.add(R.id.mContainerView,oneFragment); //提交事物 transaction.commit(); }
-
Fragment的两种引用
由于Fragment是在Android3.0加入的,目前Android中提供v4包下的和android.app.Fragment这两种,由于是Android3.0之前加入的,在之前的版本中不能使用android.app.Fragment,要使用v4包下的兼容性的Fragment,这也是目前推荐使用。
- v4包下的兼容性Fragment(推荐使用)
- v4包下的Fragment加载
// 此时只能去加载继承至v4包下的Fragment // FragmentManager的实例获取是通过getSupportFragmentManager。 private void loadFragment(){ //获取到FragmentManager的实例 FragmentManager fragmentManager = getSupportFragmentManager(); //开启事物 FragmentTransaction transaction = fragmentManager.beginTransaction(); //将Fragment添加到FrameLayout布局中。其中SecondFragment extends v4.Fragment transaction.add(R.id.mContainerView,secondFragment); //提交事物 transaction.commit(); }
- 系统本身内置的Fragment ,不兼容Android3.0以前的手机。
- 系统本身内置Fragment的加载。
1. 只能加载系统内置的Fragment 2. FragmentManager的实例获取是通过getFragmentManager。 private void loadFragment() { android.app.FragmentManager manager = getFragmentManager(); android.app.FragmentTransaction transaction1 = manager.beginTransaction(); //其中ONeFragment extends android.app.Fragment transaction1.add(R.id.mContainerView, oneFragment); transaction1.commit(); }
- v4包下的兼容性Fragment(推荐使用)
Fragment与Activity之间的通信方式
Activity传递数据到Fragment中
- setArguments
//在Fragment中构造带有参数的Fragment
public static SecondFragment newInstance(String data) {
SecondFragment secondFragment = new SecondFragment();
Bundle bundle = new Bundle();
bundle.putString("flag", data);
secondFragment.setArguments(bundle);
return secondFragment;
}
//在Activity中加入带有参数的Fragment
private void loadFragment() {
SecondFragment secondFragment = SecondFragment.newInstance("dashingqi");
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.mContainerView, secondFragment);
transaction.commit();
}
//在Fragment中获取参数
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = getArguments();
data = bundle.getString("flag");
}
- findFragmentByTag
//1. 在事物中添加Fragment时 为添加的Fragment设置一个Tag
transaction.add(R.id.mContainerView, secondFragment, "secondFragment");
//2. 在Fragment中体格一个方法用来调用传递数据
public void setData(String data) {
mTvText.setText(data);
}
//3. 在Activity中调用findFragmentByTag,后去到Fragment的实例然后嗲用方法传递数据。
econdFragment secondFragment = (SecondFragment) manager.findFragmentByTag("secondFragment");
secondFragment.setData("婷婷");
Fragment传递数据到Activity中
- 接口回调
//1. Activity实现接口,实现方法
//2. Fragment中获取到Activity实例,调用接口方法
@Override
public void onAttach(Context context) {
super.onAttach(context);
activity = (MainActivity) getActivity();
}
mTvText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
activity.setMessage("callback");
}
});
//这个地方在Fragment可以设置方法通过传递Callback实例来调用回调方法。
Fragment与Fragment之间通信
- 接口
1. SecondFragment 中传数据到OneFragment
2. 在SecondFragment声明一个接口,在Activity中实现这个接口,然后在Activity中获取到OneFragment的实例,调用OneFragment中的方法,将数据传递给OneFragment。
3. 其实就是通过Activity这个中间人,将数据传递到目标Fragment。
- 广播
1. 声明一个广播,注册监听广播(在接受数据的Fragment中)
2. 发送广播,发送带有数据的Intent,这个Intent的Action要与注册广播声明时的Action要一致。
问题记录
生命周期
- 手机锁屏:onPause() -> onSaveInstanceState()-> onStop()
- 按下Home建回到桌面: onPause() -> onSaveInstanceState() -> onStop()
- 返回到应用: onStart()-> onResume()
- 切换到其他Fragment:onPause() -> onStop()-> onDestroyView()
- 切回到Fragment:onCreateView()-> onStart()-> onResume()
- 退出应用:onPause() -> onStop() -> onDestroyView() -> onDestroy() ->onDetach()
网友评论