对话框关闭时如何切换现有片段?

How to switch existing fragments when the dialog is closed?

应用程序的主屏幕适用于 bottom navigation

并且有3个菜单,都是fragments.

按下其中一个片段上的按钮可打开 dialog fragment window。

并且当对话框关闭时,旧片段应该切换到另一个新片段。

我使用 show()hide() 而不是 replace()

MainAcitivity.java

public class MainActivity extends AppCompatActivity {
    BottomNavigationView bottomNav;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bottomNav = findViewById(R.id.bottom_nav);

        bottomNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                FragmentManager fm = getSupportFragmentManager();
                FragmentTransaction transaction = fm.beginTransaction();
                Fragment curFrag = fm.getPrimaryNavigationFragment();
                String tag = String.valueOf(item.getItemId());
                int id = item.getItemId();

                if(curFrag != null) {
                    transaction.hide(curFrag);
                }

                Fragment fragment = fm.findFragmentByTag(tag);
                if(fragment == null) {
                    if(id == R.id.list)
                        fragment = new WorkoutListFragment();
                    transaction.add(R.id.content_layout, fragment);
                }
                else {
                    transaction.show(fragment);
                }

                transaction.setPrimaryNavigationFragment(fragment);
                transaction.setReorderingAllowed(true);
                transaction.commitNow();
                return true;
            }
        });
    }

    // Switch to another fragment when the dialog is closed
    public void onFragmentChanged() {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        String tag = "ABC";

        Fragment currentFragment = fragmentManager.getPrimaryNavigationFragment();
        if (currentFragment != null) {
            fragmentTransaction.hide(currentFragment);
        }

        Fragment fragment = fragmentManager.findFragmentByTag(tag);
        if (fragment == null) {
            fragment = new WriteRoutineFragment();
            fragmentTransaction.add(R.id.container, fragment, tag);
        } else {
            fragmentTransaction.show(fragment);
        }

        fragmentTransaction.setPrimaryNavigationFragment(fragment);
        fragmentTransaction.setReorderingAllowed(true);
        fragmentTransaction.commitNow();
    }
}

DialogFragment.java


    Button startBtn;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_body_part_dialog, null);
        startBtn = view.findViewById(R.id.check);

        startBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) { 
                MainActivity activity = (MainActivity) getActivity();
                activity.onFragmentChanged(); // change fragment
                dismiss();

            }
        });

        return view;
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        dialog.setCanceledOnTouchOutside(false);

        return dialog;
    }
}

WriteRoutineFragment.java

public class WriteRoutineFragment extends Fragment {


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_write_routine, container, false);

        return rootView;
    }
}

错误

java.lang.IllegalArgumentException: No view found for id 0x7f0a0082 (com.example.writeweight:id/container) for fragment WriteRoutineFragment{f3a9b6 (137e8e27-12af-4e5a-9397-2cbdc80ed980) id=0x7f0a0082 ABC}
        at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:875)
        at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManagerImpl.java:2100)
        at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1874)
        at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1830)
        at androidx.fragment.app.FragmentManagerImpl.execSingleAction(FragmentManagerImpl.java:1696)
        at androidx.fragment.app.BackStackRecord.commitNow(BackStackRecord.java:293)
        at com.example.writeweight.activity.MainActivity.onFragmentChanged(MainActivity.java:78)
        at com.example.writeweight.fragment.BodyPartDialogFragment.onClick(BodyPartDialogFragment.java:89)
        at android.view.View.performClick(View.java:8160)
        at android.widget.TextView.performClick(TextView.java:16221)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)
        at android.view.View.performClickInternal(View.java:8137)
        at android.view.View.access00(View.java:888)
        at android.view.View$PerformClick.run(View.java:30236)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8506)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
I/Process: Sending signal. PID: 23516 SIG: 9


已添加

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activity.MainActivity">

    <FrameLayout
        android:id="@+id/content_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintBottom_toTopOf="@id/bottom_nav"/>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="?android:attr/windowBackground"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu"/>

</androidx.constraintlayout.widget.ConstraintLayout>

fragment_write_routine.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".fragment.WriteRoutineFragment">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

</FrameLayout>

当你说

fragmentTransaction.add(R.id.container, fragment, tag);

您的意思是您希望 FragmentManager 在您的布局中找到 R.id.container 并将您的片段添加到该容器中。当您使用 getSupportFragmentManager() 时,您正在使用 Activity 的 FragmentManager,因此,R.id.container 需要在您的 activity 布局中。但是,R.id.container 不在您的 activity 布局中,这就是您遇到异常的原因。

相反,您应该在 Activity 的布局中使用 的容器 - R.id.content_layout:

fragmentTransaction.add(R.id.content_layout, fragment, tag);