一、Fragment详解
生命周期.png
(1)Fragment生命周期方法
- onAttach:Fragment和Activity建立关联时调用
- onCreate:Fragment被创建时回调
- onCreateView:Fragment创建视图时调用
- onActivityCreated:Fragment相关联的Activity完成onCreate()之后调用
- onStart:启动Fragment时回调
- onResume:Fragment在前台可见,处于活动状态,用户可与之交互
- onPause:Fragment处于暂停状态,但依然可见,用户不能与之交互
- onStop:停止Fragment回调,Fragment完全不可见
- onDestroyView:Fragment中的布局被移除时调用
- onDestroy:销毁Fragment时被回调,此后接onDetach
- onDetach:Fragment和Activity解除关联时调用
(2)加载Fragment
public class LoadingFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_loading);
return view;
}
}
- 静态加载Fragment
//在Activity布局中使用<fragment>标签添加碎片
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.ee.cp.study.LoadingFragment"/>
- 动态加载Fragment
//在Activity布局添加FrameLayout控件
<FrameLayout
android:id="@+id/fl_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
//在Activity中添加Fragment界面
LoadingFragment loadingFragment = new LoadingFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fl_fragment, loadingFragment);//fragment放到布局容器
fragmentTransaction.addToBackStack(null);//用户通过返回键返回前一个fragment状态
fragmentTransaction.commit();
- Activity的FragmentManager负责调用队列中Fragment的生命周期方法,只要Fragment的状态与Activity的状态保持了同步,托管Activity的FragmentManager便会继续调用其他生命周期方法以继续保持Fragment与Activity的状态一致。
- 显示的时候先调用Activity方法在调用Fragment相应的方法;退出的时候先调用Fragment方法在调用Activity相应的方法。
- Activity需要调用Fragment那些方法并管理它,Fragment的生命周期方法是由托管Activity而不是操作系统调用的。Activity中生命周期方法都是protected,而Fragment都是public,也能印证了这一点。
(3)Fragment与Activity之间通信
- 设置点击事件的回调接口,重写点击事件将事件处理交给实现点击事件接口的Activity实现。
public class LoadingFragment extends Fragment implements View.OnClickListener {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_loading);
return view;
}
public interface FragmentOnClickListener {
void fragmentOnClickListener();
}
@Override
public void onClick(View v) {
//交给Activity处理事件
if (getActivity() instanceof FragmentOnClickListener)
((FragmentOnClickListener)getActivity()).fragmentOnClickListener();
}
}
- 实现FragmentOnClickListener接口,在fragmentOnClickListener中实现事件处理。
public class MainActivity extends AppCompatActivity implements LoadingFragment.FragmentOnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void fragmentOnClickListener() {
}
}
- 提供setFragmentClickListener方法,Activity不仅需要实现该接口,还必须显示调用该方法。
public class LoadingFragment extends Fragment implements View.OnClickListener {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_loading);
return view;
}
private FragmentOnClickListener fragmentOnClickListener;
public interface FragmentOnClickListener {
void fragmentOnClickListener();
}
public void setFragmentClickListener(FragmentOnClickListener fragmentOnClickListener) {
this.fragmentOnClickListener = fragmentOnClickListener;
}
@Override
public void onClick(View v) {
//交给Activity处理事件
if (fragmentOnClickListener != null)
fragmentOnClickListener.fragmentOnClickListener();
}
}
- 如果你Activity中包含自己管理的Fragment的引用。可以通过引用直接访问所有的Fragment的public方法
- 在Fragment中可以通过getActivity得到当前绑定的Activity的实例,然后进行操作。
二、Framgnet源码解析
总结
- show/hideFragment只是改变fragment根View的visibility,最多带上个动画效果,另外只有本身是hidden的fragment,调用show才起作用,否则没用的,fragment.onHiddenChanged会被触发;其次不会有生命周期callback触发,当然了这些操作的前提是已经被add了的fragment;
- addFragment的时候,不管加不加入回退栈都一样,经历的生命周期如下:onAttach、onCreate、onCreateView、onActivityCreate、onStart、onResume;
- removeFragment的时候,经历的生命周期如下:onPause、onStop、onDestroyView,如果不加回退栈还会继续走
- onDestroy、onDetach;remove的时候不仅从mAdded中移除fragment,也从mActive中移除了;
- attach/detachFragment的前提都是已经add了的fragment,其生命周期回调不受回退栈影响。attach的时候onCreateView、onActivityCreate、onStart、onResume会被调用;detach的时候onPause、onStop、onDestroyView会被调用,onDestroy、onDetach不会被调用;对应的fragment只是从mAdded中移除了