如何在 AppBar 下方创建一个裁剪的 NavigationDrawer?
最新的 Android Studio (3.5.3) 会生成一个全高 NavigationDrawer,我的问题是需要更改哪些内容才能获得剪裁的 NavigationDrawer?
(请不要通过链接到带有一长串古老答案的古老(例如 2015 年)问题将这个问题标记为“重复”。现在是 2020 年,我希望现在存在一种实现裁剪 NavigationDrawer 的简单方法。希望现在有一个简单的解决方案,可以很好地与 androidx 和 jetpack 导航以及 Kotlin 方法配合使用,例如setupActionBarWithNavController
. 当我上面提到使用 Android Studio 生成的代码时,我现在谈论的是 Android Studio 3.5.3,即当前最新版本,以及它的项目模板“Navigation Drawer Activity”与 Kotlin 和最低 API 级别 19,即 Android 4.4。当今天的开发人员想要找到一种方法来做到这一点,并使用 google 和 stackoverflow 进行搜索时,我们不想找到并滚动浏览包含大量旧/过时页面答案的长页面。由于这个问题现在是在 2020 年 2 月提出的,所以每个人都清楚,下面所有可能出现的答案也将晚于此。)
奇怪的是,似乎很难找到有关如何使用 Android 实现剪辑抽屉的文档。这里提到了 NavigationDrawers的两种类型(“full-height”和“clipped” ):
https://material.io/components/navigation-drawer/#standard-drawer
引用:
“标准的导航抽屉可以使用以下海拔位置之一:
At the same elevation as a top app bar (full-height) At a lower elevation than a top app bar (clipped)"
在上面的网页上,还有一个指向 android 特定页面的链接:
https://material.io/develop/android/components/navigation-view/
但是,该页面目前没有提及有关如何创建剪辑 NavigationDrawer 的任何内容。此外,该 android 页面似乎不是很更新,因为它当前链接到有关 DrawerLayout 的旧支持 v4 库。
相反,当我查看有关 DrawerLayout 的新 androidx 页面时,我仍然找不到任何有关“剪辑”抽屉的信息。(因为“剪辑”是谷歌材料设计中使用的术语,所以谷歌也应该使用相同的词在文档页面中进行搜索)。
以下是一些应该可以找到有关“剪辑”的页面的页面,但不幸的是目前没有:
https://developer.android.com/jetpack/androidx/releases/drawerlayout
https://developer.android.com/guide/navigation/navigation-ui#add_a_navigation_drawer
为了说明我在寻找什么(独立于上面可能会改变的材料设计页面),我在下面提供了一些图片。
下面的第一个屏幕截图是使用 Android Studio 3.5.3(当前是最新版本)生成 Android 应用程序以及使用 Kotlin 和最低 API 级别 19(Android 4.4)生成 Android 应用程序后的结果(有两个修改,见下文) )。
我所做的两个更改(在“activity_main.xml”中)是我从 NavigationView 中删除了 app:headerLayout 并将 android:layout_height="match_parent" 替换为 android:layout_height="wrap_content"。
然后我用 GIMP 编辑了一些截图来说明我真正想要的,如下图所示。“汉堡图标”应该可以关闭 NavigationDrawer,即使用它进行切换。
以下是使用“全高”NavigationDrawer 生成的一些相关文件,我的问题是我必须进行哪些更改才能获得如上述编辑图片中的“剪辑”NavigationDrawer?
MainActivity.kt
package com.myapplication
import android.os.Bundle
import com.google.android.material.floatingactionbutton.FloatingActionButton
import com.google.android.material.snackbar.Snackbar
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import androidx.drawerlayout.widget.DrawerLayout
import com.google.android.material.navigation.NavigationView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import android.view.Menu
class MainActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val fab: FloatingActionButton = findViewById(R.id.fab)
fab.setOnClickListener { view ->
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show()
}
val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
val navView: NavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow,
R.id.nav_tools, R.id.nav_share, R.id.nav_send
), drawerLayout
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.main, menu)
return true
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment)
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
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">
<include
layout="@layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<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:menu="@menu/activity_main_drawer" />
</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" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_dialog_email" />
</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:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/app_bar_main">
<fragment
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>