如果使用导航控制器,如何删除某些片段中的底部导航视图和工具栏?
how to remove bottom navigation view and toolbar in some fragments if using navigation controller?
我将 MainActivity 作为我的导航控制器的宿主,它有工具栏和底部导航视图
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="?attr/actionBarTheme"
android:minHeight="?attr/actionBarSize"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<fragment
android:id="@+id/nav_host_fragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/bottom_nav"
app:layout_constraintTop_toBottomOf="@+id/toolbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="@navigation/navigation_graph"
app:defaultNavHost="true"
/>
<android.support.design.widget.BottomNavigationView
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:background="@color/colorPrimary"
app:itemIconTint="@color/color_bottom_view_navigation"
app:itemTextColor="@color/color_bottom_view_navigation"
app:menu="@menu/menu_bottom_view"
app:labelVisibilityMode="labeled"
android:id="@+id/bottom_nav"/>
</android.support.constraint.ConstraintLayout>
它将承载一些片段作为底部导航视图的菜单,例如 HomeFragment
、OrderFragment
、FavouriteFragment
、CartFragment
、ProfileFragment
。
像这样:
假设 HomeFragment
中有注销按钮,如果单击它,它将移动到登录屏幕。和往常一样,登录屏幕或注册屏幕没有底部导航视图,也没有工具栏。
如果使用导航控制器,删除底部导航视图和工具栏的最佳方法是什么?
我尝试在我的导航控制器图表中使用 <Include>
标签,
所以我做了两个导航图,然后我做了 2 个 activity 来放置片段作为宿主。第一个 activity 有底部导航视图和工具栏(MainActivity,就像我上面分享的 xml 一样),另一个 activity 没有底部导航视图和工具栏
导航图如下图:
MainActivity 作为导航主机片段
AuthActivity 作为导航主机片段
但是当我使用此代码从 HomeFragment
(具有注销按钮)移动到 LoginFragment
时:
logout_button.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.action_toAuthActivity)
}
但在登录屏幕中,底部导航视图和工具栏仍然存在
我假设 auth_graph(AuthActivity 作为主机)可用于托管一些没有底部导航视图和工具栏的屏幕,例如登录屏幕、注册屏幕或忘记密码屏幕。
但是....我无法使用这种方式删除底部导航视图和工具栏
那么,如果使用导航控制器,如何删除某些片段中的底部导航视图和工具栏?
老实说,我刚刚阅读了这个问题的标题,但是..你不能只切换可见性吗?将其放入您的 MainActivity。
fun toggleBottomNavigation(visible: Boolean) {
bottomNavigationView.visibility = if (visible) {
View.VISIBLE
} else {
View.GONE
}
}
并对工具栏执行相同的操作。
NavigationUI 中目前似乎没有实现简单的解决方案。
我最后做的是在 MainActivity
中添加一个 hideBottomBar
方法,如下所示:
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
hideBottomBar(false); // to have it visible by default
}
public void hideBottomBar(boolean isHidden){
bottomBar.setVisibility(isHidden ? View.GONE : View.VISIBLE);
}
然后,在需要隐藏底部栏的片段中:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// layout inflating and stuff...
MainActivity activity = (MainActivity) getActivity();
if (activity != null)
activity.hideBottomBar(true);
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
MainActivity activity = (MainActivity) getActivity();
if (activity != null)
activity.hideBottomBar(false); // to show the bottom bar when
// we destroy this fragment
}
更简洁的是使用navigationlistener。这样,您只需要在 MainActivity 中使用 1 个函数,并且在所有要隐藏底部导航或任何其他 UI 元素(如工具栏)的片段中都不需要代码。将此函数放在 MainActivity 的 onCreate 中。
我的函数如下所示:
private fun visibilityNavElements(navController: NavController) {
navController.addOnDestinationChangedListener { _, destination, _ ->
when (destination.id) {
R.id.about_fragment,
R.id.settings_fragment,
R.id.detail_fragment,
R.id.missionPhotoFragment -> bottom_nav?.visibility = View.GONE
else -> bottom_nav?.visibility = View.VISIBLE
}
}
}
我使用 Kotlin Android Extensions 通过 ID 直接访问视图(不需要 findViewById)。
您可以访问父视图的 ID 并通过将其可见性设置为消失来隐藏底部导航,并且必须再次使其在 On Destroy 视图中可见
BottomNavigationView navView;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_add_standard, container, false);
navView = container.getRootView().findViewById(R.id.nav_view);
navView.setVisibility(View.GONE);
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
navView.setVisibility(View.VISIBLE);
}
我将 MainActivity 作为我的导航控制器的宿主,它有工具栏和底部导航视图
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="?attr/actionBarTheme"
android:minHeight="?attr/actionBarSize"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
<fragment
android:id="@+id/nav_host_fragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/bottom_nav"
app:layout_constraintTop_toBottomOf="@+id/toolbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:name="androidx.navigation.fragment.NavHostFragment"
app:navGraph="@navigation/navigation_graph"
app:defaultNavHost="true"
/>
<android.support.design.widget.BottomNavigationView
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:background="@color/colorPrimary"
app:itemIconTint="@color/color_bottom_view_navigation"
app:itemTextColor="@color/color_bottom_view_navigation"
app:menu="@menu/menu_bottom_view"
app:labelVisibilityMode="labeled"
android:id="@+id/bottom_nav"/>
</android.support.constraint.ConstraintLayout>
它将承载一些片段作为底部导航视图的菜单,例如 HomeFragment
、OrderFragment
、FavouriteFragment
、CartFragment
、ProfileFragment
。
像这样:
假设 HomeFragment
中有注销按钮,如果单击它,它将移动到登录屏幕。和往常一样,登录屏幕或注册屏幕没有底部导航视图,也没有工具栏。
如果使用导航控制器,删除底部导航视图和工具栏的最佳方法是什么?
我尝试在我的导航控制器图表中使用 <Include>
标签,
所以我做了两个导航图,然后我做了 2 个 activity 来放置片段作为宿主。第一个 activity 有底部导航视图和工具栏(MainActivity,就像我上面分享的 xml 一样),另一个 activity 没有底部导航视图和工具栏
导航图如下图:
MainActivity 作为导航主机片段
AuthActivity 作为导航主机片段
但是当我使用此代码从 HomeFragment
(具有注销按钮)移动到 LoginFragment
时:
logout_button.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.action_toAuthActivity)
}
但在登录屏幕中,底部导航视图和工具栏仍然存在
我假设 auth_graph(AuthActivity 作为主机)可用于托管一些没有底部导航视图和工具栏的屏幕,例如登录屏幕、注册屏幕或忘记密码屏幕。
但是....我无法使用这种方式删除底部导航视图和工具栏
那么,如果使用导航控制器,如何删除某些片段中的底部导航视图和工具栏?
老实说,我刚刚阅读了这个问题的标题,但是..你不能只切换可见性吗?将其放入您的 MainActivity。
fun toggleBottomNavigation(visible: Boolean) {
bottomNavigationView.visibility = if (visible) {
View.VISIBLE
} else {
View.GONE
}
}
并对工具栏执行相同的操作。
NavigationUI 中目前似乎没有实现简单的解决方案。
我最后做的是在 MainActivity
中添加一个 hideBottomBar
方法,如下所示:
@Override
protected void onCreate(Bundle savedInstanceState) {
// ...
hideBottomBar(false); // to have it visible by default
}
public void hideBottomBar(boolean isHidden){
bottomBar.setVisibility(isHidden ? View.GONE : View.VISIBLE);
}
然后,在需要隐藏底部栏的片段中:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// layout inflating and stuff...
MainActivity activity = (MainActivity) getActivity();
if (activity != null)
activity.hideBottomBar(true);
return view;
}
@Override
public void onDestroyView() {
super.onDestroyView();
MainActivity activity = (MainActivity) getActivity();
if (activity != null)
activity.hideBottomBar(false); // to show the bottom bar when
// we destroy this fragment
}
更简洁的是使用navigationlistener。这样,您只需要在 MainActivity 中使用 1 个函数,并且在所有要隐藏底部导航或任何其他 UI 元素(如工具栏)的片段中都不需要代码。将此函数放在 MainActivity 的 onCreate 中。
我的函数如下所示:
private fun visibilityNavElements(navController: NavController) {
navController.addOnDestinationChangedListener { _, destination, _ ->
when (destination.id) {
R.id.about_fragment,
R.id.settings_fragment,
R.id.detail_fragment,
R.id.missionPhotoFragment -> bottom_nav?.visibility = View.GONE
else -> bottom_nav?.visibility = View.VISIBLE
}
}
}
我使用 Kotlin Android Extensions 通过 ID 直接访问视图(不需要 findViewById)。
您可以访问父视图的 ID 并通过将其可见性设置为消失来隐藏底部导航,并且必须再次使其在 On Destroy 视图中可见
BottomNavigationView navView;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View root = inflater.inflate(R.layout.fragment_add_standard, container, false);
navView = container.getRootView().findViewById(R.id.nav_view);
navView.setVisibility(View.GONE);
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
navView.setVisibility(View.VISIBLE);
}