4)Fragment事务后台栈
在调用commit()之前,可以将事务添加到Fragment事务后台栈中(通过调用addToBackStatck())。这个后台栈由Activity管理,并且允许用户通过按BACK键回退到前一个Fragment状态。
下面的代码中一个Fragment代替另一个Fragment,并且将之前的Fragment状态保留在后台栈中:
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.Fragment_container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
注:
- 如果添加多个变更事务(例如另一个add()或者remove())并调用addToBackStack(),那么在调用commit()之前的所有应用的变更被作为一个单独的事务添加到后台栈中,并且BACK键可以将它们一起回退
- 当移除一个Fragment时,如果调用了addToBackStack(),那么之后Fragment会被停止,如果用户回退,它将被恢复过来
- 调用commit()并不立刻执行事务,相反,而是采取预约方式,一旦Activity的界面线程(主线程)准备好便可运行起来。然而,如果有必要的话,你可以从界面线程调用executePendingTransations()立即执行由commit()提交的事务
- 只能在Activity保存状态(当用户离开Activity时)之前用commit()提交事务。如果你尝试在那时之后提交,会抛出一个异常。这是因为如果Activity需要被恢复,提交后的状态会被丢失。对于这类丢失提交的情况,可使用commitAllowingStateLoss()
5)与Activity交互
Activity中已经有了该Fragment的引用,直接通过该引用进行交互。
如果没引用可以通过调用Fragment的函数findFragmentById()或者findFragmentByTag(),从FragmentManager中获取Fragment的索引,例如:
ExampleFragment Fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_Fragment);
在Fragment中可以通过getActivity得到当前绑定的Activity的实例,创建Activity事件回调函数,在Fragment内部定义一个回调接口,宿主Activity来实现它。Activity向Fragment传参:
很多人提到向Fragment传递参数会下意识想到重写Fragment的构造方法并传入自己的参数。事实上,这种方式时极不科学和极不安全的,因为Android在很多场景下都会出现Fragment的重建情况(比如横竖屏的切换),但是重建的时候系统并不会使用你编写的Fragment的构造方法而是调用Fragment默认的构造方法,这个时候你传的参数将会消失导致各种异常。那么如何更安全地向Fragment传递参数呢,Google官方推荐的setArguments方法:
- 初始化Fragment实例并setArguments
DiscoverFragment discoverFragment = new DiscoverFragment();
Bundle bundle = new Bundle();
bundle.putString("email", email);
discoverFragment.setArguments(bundle);
- 在Fragment中拿到Arguments:
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.Fragment_discover, null);
Bundle bundle = getArguments();
//这里就拿到了之前传递的参数
email = bundle.getString("email");
return view;
}