如何在 Kotlin 的同一个活动中实现 DrawerLayout 和 bottomNavigation?

如何解决如何在 Kotlin 的同一个活动中实现 DrawerLayout 和 bottomNavigation?

老实说,我希望我的应用看起来像 Yahoo!

最近我正在开发一个应用程序,它需要一个使用 4 个不同片段和一个菜单sidesman_nav 和 bottom_navigation_menu)的底部导航以及一个具有不同 NavigationView 和菜单 mobile_navigation 和 main_drawer_menu) 连接到另一个片段或意图。 到目前为止,我还没有能够完全实现运行良好的 mobile_navigation。

我能够实现完美的底部导航,另一方面,我能够使用他们的菜单实现抽屉布局,但是当我尝试导航到抽屉布局的片段时,它不会回到最后一个状态,换句话说,它不会回到显示底部导航和关闭应用程序的片段。
现在我使用 content_main.xml 中的片段元素将 bottom_navigation 的片段显示为 NavHostFragment 并显示与 DrawerLayout 相关的项目片段,我使用的是带有 id 容器的 ConstratinLayout。因此,我可以查看 DrawerLayout 的片段,但无法在应用栏中看到后退按钮,当我返回时,它会完全关闭应用。
所以我可能需要实现另一个片段,但我不知道它是否正确,而且我也不知道如何实现。我的另一个想法是在 DrawerLayout 片段或主活动本身中实现 ​​onBackpressed 函数,最后我对任何其他解决方案持开放态度,我需要在底部导航的片段之间导航而不会丢失它们的状态(大功告成),当用户进入抽屉布局的一个片段时,他们可以通过以下三种可能的方式之一返回到最后的状态:

  1. 查看应用栏中的后退按钮
  2. 点击底部导航按钮
  3. 回去吧

Bottom navigation working
Drawer layout showing
Actual state 显示片段但无法返回且底部按钮不起作用。

这是我的实现:

代码

MainActivity.kt

class MainActivity : AppCompatActivity(),NavigationView.OnNavigationItemSelectedListener {  

    private val homeFragment = HomeFragment()
    private val newxFragment = NewxFragment()
    private val searchFragment = SearchFragment()
    private val marketsFragment = MarketsFragment()
    private val fragmentManager = supportFragmentManager

    private var activeFragment: Fragment = homeFragment

    private lateinit var appBarConfiguration: AppBarConfiguration

    private lateinit var fusedLocationClient: FusedLocationProviderClient

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val toolbar: Toolbar = findViewById(R.id.toolbar)
        setSupportActionBar(toolbar)

        val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
        val navView: NavigationView = findViewById(R.id.nav_view)
        val navController = findNavController(R.id.nav_host_fragment)
        appBarConfiguration = AppBarConfiguration(navController.graph,drawerLayout)
        setupActionBarWithNavController(navController,appBarConfiguration)
        navView.setupWithNavController(navController)
        navView.setNavigationItemSelectedListener(this)


        fragmentManager.beginTransaction().apply {
            add(R.id.nav_host_fragment,newxFragment,getString(R.string.newxs)).hide(newxFragment)
            add(R.id.nav_host_fragment,searchFragment,getString(R.string.search)).hide(searchFragment)
            add(R.id.nav_host_fragment,marketsFragment,getString(R.string.markets)).hide(marketsFragment)
            add(R.id.nav_host_fragment,homeFragment,getString(R.string.home))
        }.commit()
        initListeners()

    }

    override fun onBackpressed() {
        if (drawer_layout.isDrawerOpen(GravityCompat.START)) {
            drawer_layout.closeDrawer(GravityCompat.START)
        }
        else{
            super.onBackpressed()
        }
    }


    private fun initListeners() {
        bottomNavigationView.setonNavigationItemSelectedListener { menuItem ->
            when (menuItem.itemId) {
                R.id.homeFragment -> {
                    fragmentManager.beginTransaction().hide(activeFragment).show(homeFragment)
                        .commit()
                    activeFragment = homeFragment
                    toolbar.title = "Home"
                    true
                }
                R.id.newxFragment -> {
                    fragmentManager.beginTransaction().hide(activeFragment).show(newxFragment)
                        .commit()
                    activeFragment = newxFragment
                    toolbar.title = "Newx"
                    true
                }
                R.id.searchFragment -> {
                    fragmentManager.beginTransaction().hide(activeFragment).show(searchFragment)
                        .commit()
                    activeFragment = searchFragment

                    toolbar.title = "Search"
                    true
                }
                R.id.marketsFragment -> {
                    fragmentManager.beginTransaction().hide(activeFragment).show(marketsFragment)
                        .commit()
                    activeFragment = marketsFragment

                    toolbar.title = "Markets"
                    true
                }

                else -> false
            }
        }
    }


    override fun onNavigationItemSelected(item: MenuItem): Boolean {

        var fragment: Fragment? = null
        when (item.itemId) {

            R.id.info -> {
                fragment = InfoFragment()
                toolbar.title = "Info"
            }
            R.id.configuration -> {
                fragment = ConfigurationFragment()
                toolbar.title = "Configuration"
            }
            R.id.notification -> {
                fragment = NotificationFragment()
                toolbar.title = "Notification"
            }
            R.id.comments -> {
                fragment = CommentsFragment()
                toolbar.title = "Comments"
            }
            R.id.help -> {
                fragment = HelpFragment()
                toolbar.title = "Help"
            }
            R.id.cond_priv -> {
                fragment = CondPrivFragment()
                toolbar.title = "Conditions and Privacy"
            }
        }
        if (fragment != null) {
            fragmentManager.beginTransaction().replace(R.id.container,fragment)
                .commit()
        }
        drawer_layout.closeDrawer(GravityCompat.START)
        return true
    }

    override fun onSupportNavigateUp(): Boolean {
        val navController = findNavController(R.id.nav_host_fragment)
        return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
    }

    public override fun onPause() {
        super.onPause()
    }

    public override fun onResume() {
        super.onResume()
    }

    public override fun onDestroy() {
        super.onDestroy()
    }
}

布局

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
        <include
            layout="@layout/app_bar_main"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>

    <com.google.android.material.navigation.NavigationView

        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/main_drawer_menu">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="@dimen/mdtp_date_picker_title_padding"
            android:paddingBottom="@dimen/activity_vertical_margin"
            android:layout_gravity="bottom"
            android:text="@string/developer"
            android:textAlignment="center"
            android:textColor="@color/colorThree"
            tools:ignore="RtlCompat" />
    </com.google.android.material.navigation.NavigationView>

</androidx.drawerlayout.widget.DrawerLayout>

app_bar_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </com.google.android.material.appbar.AppBarLayout>

    <include layout="@layout/content_main"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

content_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:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/app_bar_main">

    <RelativeLayout
        android:id="@+id/rlAdView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorOne"
        app:layout_constraintBottom_toTopOf="@+id/nav_host_fragment"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <com.google.android.gms.ads.AdView xmlns:ads="http://schemas.android.com/apk/res-auto"
            android:id="@+id/adView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            ads:adSize="BANNER"
            ads:adUnitId="ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx"
            tools:ignore="MissingConstraints" />
    </RelativeLayout>

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@id/bottomNavigationView"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/rlAdView"
        app:navGraph="@navigation/sidesman_nav" />

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNavigationView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorOne"
        app:itemIconTint="@color/colorTwo"
        app:itemTextColor="@color/colorTwo"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/bottom_navigation_menu" />

</androidx.constraintlayout.widget.ConstraintLayout>

mobile_navigation.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/mobile_navigation"
    app:startDestination="@id/infoFragment">

    <fragment
        android:id="@+id/commentsFragment"
        android:name="com.trinuxapp.cryptomarket.fragments.CommentsFragment"
        android:label="CommentsFragment"
        tools:layout="@layout/fragment_comments"/>
    <fragment
        android:id="@+id/condPrivFragment"
        android:name="com.trinuxapp.cryptomarket.fragments.CondPrivFragment"
        android:label="CondPrivFragment"
        tools:layout="@layout/fragment_cond_priv_"/>
    <fragment
        android:id="@+id/configurationFragment"
        android:name="layout.ConfigurationFragment"
        android:label="ConfigurationFragment"
        tools:layout="@layout/fragment_configuration"/>
    <fragment
        android:id="@+id/notificationFragment"
        android:name="com.trinuxapp.cryptomarket.fragments.NotificationFragment"
        android:label="NotificationFragment"
        tools:layout="@layout/fragment_notification"/>
    <fragment
        android:id="@+id/helpFragment"
        android:name="com.trinuxapp.cryptomarket.fragments.HelpFragment"
        android:label="HelpFragment"
        tools:layout="@layout/fragment_help"/>
    <fragment
        android:id="@+id/infoFragment"
        android:name="com.trinuxapp.cryptomarket.fragments.InfoFragment"
        android:label="InfoFragment"
        tools:layout="@layout/fragment_info"/>

</navigation>

sidesman_nav.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/sidesman_nav"
    app:startDestination="@id/homeFragment"
    tools:ignore="Unusednavigation">

    <fragment
        android:id="@+id/homeFragment"
        android:name="com.trinuxapp.cryptomarket.fragments.HomeFragment"
        android:label="Home"
        tools:layout="@layout/home_fragment" />

    <fragment
        android:id="@+id/newxFragment"
        android:name="com.trinuxapp.cryptomarket.fragments.NewxFragment"
        android:label="Newx"
        tools:layout="@layout/newx_fragment">
        <action
            android:id="@+id/action_newxFragment_to_eventDetailFragment"
            app:destination="@id/eventDetailFragment" />
    </fragment>
    <fragment
        android:id="@+id/searchFragment"
        android:name="com.trinuxapp.cryptomarket.fragments.SearchFragment"
        android:label="discover"
        tools:layout="@layout/search_fragment" />
    <fragment
        android:id="@+id/marketsFragment"
        android:name="com.trinuxapp.cryptomarket.fragments.MarketsFragment"
        android:label="Markets"
        tools:layout="@layout/markets_fragment" />
    <fragment
        android:id="@+id/eventDetailFragment"
        android:name="com.trinuxapp.cryptomarket.fragments.EventDetailFragment"
        android:label="EventDetailFragment">
        <argument
            android:name="eventItem"
            app:argType="com.trinuxapp.cryptomarket.models.EventItem"
            app:nullable="true" />
    </fragment>

</navigation>

bottom_navigation_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/homeFragment"
        android:icon="@drawable/ic_baseline_home_24"
        android:title="@string/home" />
    <item
        android:id="@+id/newxFragment"
        android:icon="@drawable/ic_baseline_notifications_active_24"
        android:title="@string/newxs" />
    <item
        android:id="@+id/searchFragment"
        android:icon="@drawable/ic_baseline_search_24"
        android:title="@string/search" />
    <item
        android:id="@+id/marketsFragment"
        android:icon="@drawable/ic_baseline_bar_chart_24"
        android:title="@string/markets" />

</menu>

main_drawer_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:showIn="navigation_view">

    <item
        android:id="@+id/info"
        android:icon="@drawable/ic_baseline_info_24"
        android:title="@string/info" />
    <item
        android:id="@+id/configuration"
        android:icon="@drawable/ic_baseline_settings_24"
        android:title="@string/configuration" />
    <item
        android:id="@+id/notification"
        android:icon="@drawable/ic_baseline_notifications_active_24"
        android:title="@string/notification" />
    <item
        android:id="@+id/comments"
        android:icon="@drawable/ic_baseline_comment_24"
        android:title="@string/comments" />
    <item
        android:id="@+id/help"
        android:icon="@drawable/ic_baseline_help_24"
        android:title="@string/help" />
    <item
        android:id="@+id/cond_priv"
        android:icon="@drawable/ic_baseline_security_24"
        android:title="@string/cond_priv" />
</menu>

styles.xml

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorFive</item>
        <item name="colorPrimaryDark">@color/colorOne</item>
    </style>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.MaterialComponents.Dark.ActionBar" />

    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.MaterialComponents.Light" />
</resources>

解决方法

不是将底部导航放在活动中,而是将其放在根据抽屉菜单显示的片段中。我不会详细介绍,因为它很简单,你可以自己解决。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?