如果使用导航控制器,如何删除某些片段中的底部导航视图和工具栏?

Posted

技术标签:

【中文标题】如果使用导航控制器,如何删除某些片段中的底部导航视图和工具栏?【英文标题】:how to remove bottom navigation view and toolbar in some fragments if using navigation controller? 【发布时间】:2019-06-27 21:14:34 【问题描述】:

我有 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_
        android:layout_
        tools:context=".MainActivity">

    <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_
            android:layout_
            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_
            android:layout_
            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_
            android:layout_
            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>

它将托管一些片段作为底部导航视图的菜单,例如HomeFragmentOrderFragmentFavouriteFragmentCartFragmentProfileFragment

像这样:

假设HomeFragment 中有logOut 按钮,如果单击它,它将移动到登录屏幕。像往常一样,登录屏幕或注册屏幕没有底部导航视图,也没有工具栏。

如果使用导航控制器,那么删除底部导航视图和工具栏的最佳方法是什么?

我尝试在导航控制器图中使用&lt;Include&gt; 标签,

所以我制作了两个导航图,然后制作了 2 个活动以将片段放置为主机。第一个活动有底部导航视图和工具栏(MainActivity,就像我上面分享的xml),另一个活动没有底部导航视图和工具栏

导航图如下图所示:

MainActivity 作为导航主机片段

AuthActivity 作为导航主机片段

但是当我使用此代码从HomeFragment(具有注销按钮)移动到LoginFragment 时:

logout_button.setOnClickListener 
            Navigation.findNavController(it).navigate(R.id.action_toAuthActivity)

        

但在登录屏幕底部导航视图和工具栏仍然存在

我假设 auth_graph(作为主机的 AuthActivity)可用于托管一些没有底部导航视图和工具栏的屏幕,例如登录屏幕、注册屏幕或忘记密码屏幕。

但是....我无法使用这种方式删除底部导航视图和工具栏

如果使用导航控制器,如何在某些片段中移除底部导航视图和工具栏?

【问题讨论】:

【参考方案1】:

更简洁的是使用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)。

【讨论】:

【参考方案2】:

目前在 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
    

【讨论】:

【参考方案3】:

您可以访问父视图的 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);

【讨论】:

【参考方案4】:

老实说,我刚刚阅读了这个问题的标题,但是.. 你不能切换可见性吗?把它放在你的 MainActivity 中。

fun toggleBottomNavigation(visible: Boolean) 
    bottomNavigationView.visibility = if (visible) 
        View.VISIBLE
     else 
        View.GONE
    

并对工具栏执行相同的操作。

【讨论】:

以上是关于如果使用导航控制器,如何删除某些片段中的底部导航视图和工具栏?的主要内容,如果未能解决你的问题,请参考以下文章

如何在更改全屏/上方导航时使用导航组件 navhostfragment

底部导航 如何从片段内部更改片段

底部导航视图中的每个选项卡单击都会重新加载片段

如何在android中使用底部导航视图时恢复片段状态?

通过底部导航栏更改片段时恢复片段状态

如何在底部导航片段(或导航抽屉)之间传递数据?