Android 带导航组件的 popper 导航
Android popper navigation with Navigation component
我有两个片段 FirstFragment 和 WelcomeFragment ,
在 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% 的时间用户获得更快的体验(他们只加载一个片段),依赖于您的 startDestination
的 NavigationUI
助手正常工作,并且 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
我有两个片段 FirstFragment 和 WelcomeFragment ,
在 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% 的时间用户获得更快的体验(他们只加载一个片段),依赖于您的 startDestination
的 NavigationUI
助手正常工作,并且 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