一、概述
上一篇已经说明了Fragment的生命周期,以及基础的使用方法和一些api的作用。但是想要在项目中使用好Fragment必须能够清晰明白的管理好它的状态,以下会介绍实际开发会遇到的一些场景。
二、Fragment回退栈管理
Activity是由任务栈管理的,遵循先进后出的原则,Fragment也可以实现类似的栈管理,从而实现多个Fragment先后添加后可以返回上一个Fragment,当activity容器内没有Fragment时回退则退出Activity。
具体方法:FragmentTransaction.addToBackStack(String) // 通常传入null即可
代码如下:
Fragment f = new Fragment();
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ftx = fm.beginTransaction();
ftx.replace(R.id.fragment_container, f, "ONE");
ftx.addToBackStack(null);
ftx.commit();
注:
1.activity的第一个Fragment(根Fragment)可以不添加回退栈,这样最后一个Fragment按返回时就不会空白而是直接退出activity。
2.调用addToBackStack(null)将当前的事务添加到了回退栈,调用replace方法后Fragment实例不会被销毁,但是视图层次会被销毁,即会调用onDestoryView和onCreateView。若需保存当前fragment视图状态,则可以使用hide后add新的Fragment
三、Fragment与Activity通信
a、如果Activity中包含自己管理的Fragment的引用,可以通过引用直接访问所有的Fragment的public方法
b、如果Activity中未保存任何Fragment的引用,可以通过每个Fragment都有一个唯一的TAG或者ID使用getFragmentManager.findFragmentByTag()或者findFragmentById()获得任何Fragment实例,然后进行操作。
c、在Fragment中可以通过getActivity得到当前绑定的Activity的实例,然后进行操作。
注:如果在Fragment中需要Context,可以通过调用getActivity(),如果该Context需要在Activity被销毁后还存在,则使用getActivity().getApplicationContext()。
推荐方式:
1.接口(Fragment返回数据给Activity)
Fragment部分代码:
public class TestFragment extends Fragment {
private OnSaveListener listener;
public void setListener(OnSaveListener listener) {
this.listener = listener;
}
public interface OnSaveListener {
void onSaveFinished(boolean result);
void onSaveStart();
}
@OnClick(R.id.btn_save)
public void save() {
....
listener.onSaveFinished(true);
}
}
Activity部分代码:
TestFragment f = new TestFragment();
f.setListener(new ShowCheckFragment.OnSaveListener() {
@Override
public void onSaveFinished(boolean result) {
......
}
@Override
public void onSaveStart() {
......
}
});
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.fragment_container, f);
fragmentTransaction.commit();
2.Fragment Arguments(传递数据到Fragment中)
Fragment部分代码:
public class TestFragment extends Fragment
{
private String mArgument;
public static final String ARGUMENT = "argument";
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Bundle bundle = getArguments();
if (bundle != null)
mArgument = bundle.getString(ARGUMENT);
}
/**
* 传入需要的参数,设置给arguments
* @param argument
* @return
*/
public static TestFragment newInstance(String argument)
{
Bundle bundle = new Bundle();
bundle.putString(ARGUMENT, argument);
TestFragment f = new TestFragment();
f.setArguments(bundle);
return f;
}
Fragment添加newInstance静态方法给实例化时调用,将需要的参数传入,设置到bundle中,然后setArguments(bundle),最后在onCreate中进行获取(Activity之间的Intent调用也可以采取类似方式,详见郭霖大神的第一行代码Activity章节);
注:
setArguments方法必须在fragment创建以后,添加给Activity前完成。千万不要先调用了add,然后设