如何解决如何在 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 函数,最后我对任何其他解决方案持开放态度,我需要在底部导航的片段之间导航而不会丢失它们的状态(大功告成),当用户进入抽屉布局的一个片段时,他们可以通过以下三种可能的方式之一返回到最后的状态:
- 查看应用栏中的后退按钮
- 点击底部导航按钮
- 回去吧
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 举报,一经查实,本站将立刻删除。