这里我们有两种方法:
直接在 Fragment 中获取托管它的 activity 中的 FragmentManager,然后直接提交事务进行替换:
// AFragment.java (这里是从 AFragment 跳转到 BFragment)
BFragment bFragment = BFragment.newInstance();
FragmentManager fm = getActivity().getSupportFragmentManager();
fm.beginTransaction()
.replace(R.id.fragment_container, bFragment)
.commit();
这种方法简单暴力,但不可取。why?因为我们在开发中使用 fragment 的目的就是能够让界面能得到复用,也就是让 fragment 保持独立性,而不需要知道托管它的 activity 到底是哪一个。
上面这段示例可以看到,在 AFragment 中我们将 BFragment 添加给了 FragmentActivity(托管它们的 Activity),而且我们还硬性的知道 FragmentActivity 的布局中包含 ID 为 fragment_container 的组件。而作为 Fragment 并不应该知道这些细节,这样就会导致这个 Fragment 的托管 Activity 只能是 FragmentActivity,所以我们详细看一下第二种方法,并在开发过程中使用这种方式。
通过回调接口的方式进行跳转。通过在 Fragment 中定义接口的方式,我们把需要托管 activity 处理的工作任务都交给 activity 本身来处理,也就是托管 activity 负责实现要托管的 Fragment 中的接口,然后 Fragment 直接调用托管 activity 的实现就好了。这样 Fragment 就不需要关心它的托管者是谁了,只要实现它的接口就万事大吉了。
下面我们来实现一下:
a. 在 AFragment 中定义回调接口
// AFragment.java
private CallbackAFragment mCallbackAFragment;
public interface CallbackAFragment{
void skipToBFragment();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mCallbackAFragment = (CallbackAFragment) context;
}
@Override
public void onDetach() {
super.onDetach();
mCallbackAFragment = null;
}
可以看到,我们首先定义了一个成员变量,用于存放实现 Callbacks 接口的对象,而实现这个接口的对象就是托管它的 activity,因为 fragment 添加到 activity 时的生命周期回调方法为 onAttach(),所以我们直接在这个方法中为 mCallbacks 赋值。然后在相应的生命周期销毁方法中将 mCallbacks 设置为 null,以保证该 Fragmeng 与该 activity 不在有关联性。
b. 在 AFragment 中定义回调接口
最后,托管该 Fragment 的 activity 实现上面定义的接口即可。
下面是完整 demo:
// FragmentActivity.java
public class FragmentActivity extends AppCompatActivity implements AFragment.CallbackAFragment, BFragment.CallbackBFragment {
private FragmentManager mManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mManager = getSupportFragmentManager();
Fragment fragment = mManager.findFragmentById(R.id.fragment_container);
if(fragment == null){
fragment = AFragment.newInstance();
mManager.beginTransaction()
.add(R.id.fragment_container, fragment)
.commit();
}
}
@Override
public void skipToBFragment() {
BFragment bFragment = BFragment.newInstance();
mManager.beginTransaction()
.replace(R.id.fragment_container, bFragment)
.commit();
}
@Override
public void skipToAFragment() {
AFragment aFragment = AFragment.newInstance();
mManager.beginTransaction()
.replace(R.id.fragment_container, aFragment)
.commit();
}
}
// AFragment.java
public class AFragment extends Fragment {
private CallbackAFragment mCallbackAFragment;
public interface CallbackAFragment{
void skipToBFragment();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mCallbackAFragment = (CallbackAFragment) context;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.a_fragment, container, false);
Button button = view.findViewById(R.id.a_fragment_btn);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 方法一: 跳转到 BFragment
// BFragment bFragment = BFragment.newInstance();
// FragmentManager fm = getActivity().getSupportFragmentManager();
// fm.beginTransaction()
// .replace(R.id.fragment_container, bFragment)
// .commit();
mCallbackAFragment.skipToBFragment();
}
});
return view;
}
public static AFragment newInstance() {
return new AFragment();
}
@Override
public void onDetach() {
super.onDetach();
mCallbackAFragment = null;
}
}
// BFragment.java
public class BFragment extends Fragment {
private CallbackBFragment mCallbackBFragment;
public interface CallbackBFragment{
void skipToAFragment();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mCallbackBFragment = (CallbackBFragment)context;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.b_fragment, container, false);
Button button = view.findViewById(R.id.b_fragment_btn);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 方法一: 跳转到 AFragment
// AFragment aFragment = AFragment.newInstance();
// FragmentManager fm = getActivity().getSupportFragmentManager();
// fm.beginTransaction()
// .replace(R.id.fragment_container, aFragment)
// .commit();
mCallbackBFragment.skipToAFragment();
}
});
return view;
}
public static BFragment newInstance() {
return new BFragment();
}
@Override
public void onDetach() {
super.onDetach();
mCallbackBFragment = null;
}
}
// a_fragment.xml
// b_fragment.xml
// activity_main.xml