Android 带导航组件的 popper 导航

Android popper navigation with Navigation component

我有两个片段 FirstFragmentWelcomeFragment ,

FirstFragment 我有一些动画,我从服务器加载数据然后我导航到 WelcomeFragment 使用 NavController :

navController.navigate(R.id.action_firstFragment_to_welcomeFragment);

我的nav_graph是这样的:

<fragment
        android:id="@+id/firstFragment"
        android:name="com.flyeducation.UI.FirstFragment"
        android:label="fragment_first"
        tools:layout="@layout/fragment_first">
        <action
            android:id="@+id/action_firstFragment_to_welcomeFragment"
            app:destination="@id/welcomeFragment"
            app:enterAnim="@anim/fade_in"
            app:exitAnim="@anim/fade_out"
            app:popEnterAnim="@anim/fade_in"
            app:popExitAnim="@anim/fade_out" />
    </fragment>

我希望有这种行为:

navigating from FirstFragment to WelcomeFragment but not having the ability to go back to FirstFragment when pressing the back button the app should close like pressing the home Button and when coming back staying in the WelcomeFragment

来自我在 nav_graph XML 中尝试的文档:

app:popUpTo="@id/firstFragment"
app:popUpToInclusive="true"

应用程序关闭但当我返回它时,它确实从 FirstFragment 重新开始并且没有保持我想要的状态,它停留在 WelcomeFragment

从其他问题我也在 WelcomeFragment 中尝试了这个:

navController.popBackStack(R.id.firstFragment, true);

任何人都可以帮助我实现想要的行为

编辑:

我最终拦截了 onKeyDown 并在我的 WelcomeFragment

上按下 onKeyDown 时模拟了主页点击

这在我的 WelcomeFragment

public void myOnKeyDown(int key_code, Context context){
        openDialog(context);
    }

    public void openDialog(final Context context) {
            new AlertDialog.Builder(context)
                    .setTitle("Exit ! ")
                    .setMessage("Are you sure you wanna quit our App , we will miss you !")
                    .setNegativeButton(android.R.string.cancel, null) // dismisses by default
                    .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            Intent i = new Intent(Intent.ACTION_MAIN);
                            i.addCategory(Intent.CATEGORY_HOME);
                            context.startActivity(i);
                        }
                    })
                    .create()
                    .show();
        }

这在我的 Activity 中:

@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        ((WelcomeFragment) WelcomeFragment).myOnKeyDown(keyCode, this);
        return false ;
    }

This has give me the behaviour i want but i do not think it is best practice

您永远不应该弹出图表的起始目的地。根据 Principles of Navigation:

Note: An app might have a one-time setup or series of login screens. These conditional screens should not be considered start destinations because users see these screens only in certain cases.

您应该按照 first time user experience documentation 将用户从您的 WelcomeFragment 重定向到您的 FirstFragment,仅在用户尚未通过该屏幕进入的情况下。

通过遵循此设置,99% 的时间用户获得更快的体验(他们只加载一个片段),依赖于您的 startDestinationNavigationUI 助手正常工作,并且 deep links 也将正常工作。

所以这是在我的案例中使用的正确解决方案,它将具有与问题中描述的相同的行为,就像我在 MainActivity

中覆盖 onKeyDown 时的行为一样]
OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
            @Override
            public void handleOnBackPressed() {
                openDialog(getContext());
            }
        };
        requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), callback);

另一条线索:

app:popUpTo="@id/fragment" 

片段在后台栈时使用

app:popUpToInclusive="true"

将清除堆栈,直到达到 app:popUpTo

中的片段 ID

此处描述popUpTo and popUpToInclusive