同一个 Activity 中 fragment 之间的跳转处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yz_cfm/article/details/89502054

这里我们有两种方法:

方法一:

    直接在 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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:gravity="center">
    <Button
        android:id="@+id/a_fragment_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="50sp"
        android:textColor="@android:color/black"
        android:text="A Fragment"
        android:textAllCaps="false"/>
</LinearLayout>
// b_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:gravity="center">
    <Button
        android:id="@+id/b_fragment_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="50sp"
        android:textColor="@android:color/black"
        android:text="B Fragment"
        android:textAllCaps="false"/>
</LinearLayout>
// activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

猜你喜欢

转载自blog.csdn.net/yz_cfm/article/details/89502054