敞开成长之旅!这是我参加「日新计划 2 月更文应战」的第 19 天,点击查看活动概况
前言
本篇主要是为了弥补上一篇(安卓组件学习——NavigationView导航视图 – ())缺少的前置内容,由于之前我一向认为NavigationView便是咱们的滑动菜单,可是到布局部分才发现,咱们是运用了DrawerLayout抽屉布局与NavigationView导航视图,一起组合成滑动菜单(实现侧滑交互体验)。
正文
废话不多说,咱们直接开写,先上咱们的布局,将一般的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"
android:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</FrameLayout>
</androidx.drawerlayout.widget.DrawerLayout>
咱们能够看到与之前的布局不同,咱们运用了DrawerLayout抽屉布局作为最外层,在帧布局里咱们将ToolBar作为它的子布局,这便是整体的布局结构,接下来咱们顺次介绍。
ToolBar的运用
首先是ToolBar,其实便是标题栏,不过与ActionBar不一样,ActionBar只能位于Activity的顶部,而ToolBar则扩展性更高,更为灵活。
要运用ToolBar,咱们得了解标题栏为何会默认显现,其实这源于咱们为项目指定的主题:
在清单文件中咱们会指定咱们的主题,而其就定义在咱们的res/values/theme.xml文件中:
DarkActionBar代表咱们采用了深色的ActionBar主题,这就会为咱们项目的页面带上ActionBar标题栏,当然,咱们现在项目还有一个values-night文件夹是放置夜晚主题的:
由于咱们要运用ToolBar来替代原有的ActionBar,所以咱们先把主题换成不带ActionBar的NoActionBar:
<style name="Theme.MaterialDemo" parent="Theme.MaterialComponents.Light.NoActionBar">
Light.NoActionBar是淡色主题,即主体部分为淡色而陪衬部分为深色,而不带Light的NoActionBar是深色主题。
设置好这些之后,咱们就能在之前的布局代码中运用咱们的ToolBar,这儿对之前的代码中的特点进行一些解说,咱们能够看到app:xxx这种特点写法,这是为了兼容老体系,由于有的特点特别是Material特点是老体系不存在的,为了兼容咱们就不能再用android:xxx这种写法,而ToolBar布局里的android:theme特点是让咱们为ToolBar单独指定深色主题,这就能和其他没运用ToolBar的页面区分开,但这时假如ToolBar上有菜单按钮,这时弹出的菜单也会变成深色,这就看着很不舒畅,所以咱们又运用app:popupTheme去设置弹出的菜单项为淡色主题。
接着咱们在Activity中运用该ToolBar:
setSupportActionBar(binding.toolbar)
很简略,就一句代码咱们放入onCreate()办法中即可,即把ToolBar的实例传入setSupportActionBar办法中。
此外,咱们标题栏中的文字内容也是能够改动的,回到清单文件AndroidManifest.xml,咱们为该activity标签加上label标签指定咱们想要的文字内容即可。
不过现在的ToolBar过于单调,所以咱们可认为其加一些小组件,这和之前的Menu做法相似(安卓开发基础——Menu菜单的运用 – ()),咱们在menu文件夹里去创立一个新的menu资源文件toolbar.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/backup"
android:icon="@drawable/ic_backup"
android:title="Backup"
app:showAsAction="always" />
<item
android:id="@+id/delete"
android:icon="@drawable/ic_delete"
android:title="Delete"
app:showAsAction="ifRoom" />
<item
android:id="@+id/settings"
android:icon="@drawable/ic_settings"
android:title="Settings"
app:showAsAction="never" />
</menu>
这儿咱们有新的特点 app:showAsAction用来设置按钮显现方位,别离有always表明永久显现在toolbar中但屏幕方位不行就不显现,而ifRoom则是假如屏幕够就显现在toolbar上,不行就折叠到菜单中显现,最后的never则是一向显现在菜单中,要注意的是,咱们的按钮在Toolbar上就只会显现图片,而菜单中则只会显现文字,接着咱们在Activity中与Menu操作相似,复写咱们的onOptionsItemSelected办法来对按钮操控点击事情等,复写咱们的onCreateOptionsMenu办法去载入咱们的toolbar:
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.toolbar, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> binding.drawerLayout.openDrawer(GravityCompat.START)
R.id.backup -> Toast.makeText(this, "You clicked Backup", Toast.LENGTH_SHORT).show()
R.id.delete -> Toast.makeText(this, "You clicked Delete", Toast.LENGTH_SHORT).show()
R.id.settings -> Toast.makeText(this, "You clicked Settings", Toast.LENGTH_SHORT).show()
}
return true
}
DrawerLayout抽屉布局的运用
这个更为简略,并且最好和NavigationView组合运用,否则款式太丑,在布局中咱们在文章正文第一个代码中已经看到便是写在最外层,然后便是一些特点操控,可是是写在第二个子控件上的(第一个是里边有ToolBar的FrameLayout),比如咱们上篇说的NavigationView:
<com.google.android.material.navigation.NavigationView
android:id="@+id/navView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/nav_menu"
app:headerLayout="@layout/nav_header"/>
咱们设置了android:layout_gravity=”start”,这是必须指定的,由于这是用来告知DrawerLayout滑动菜单是在屏幕的左边仍是右边,即left左边,right右边,而咱们的start是根据体系设置的语言习惯的,咱们的汉语便是从左到右,即start为左,而阿拉伯语则从右到左,所以和咱们也正好相反,start就变成右边。
设置好布局,咱们Activity也要调整相应代码:
supportActionBar?.let {
it.setDisplayHomeAsUpEnabled(true)
it.setHomeAsUpIndicator(R.drawable.ic_menu)
}
首先让咱们的滑动菜单图标显现出来,然后和Menu一样复写咱们的onOptionsItemSelected办法,运用openDrawer办法传入GravityCompat.START让图标显现在最左边(开端)而不是ToolBar的Home返回按钮。
这样一来咱们就完成了整个滑动菜单,结合上篇的NavigationView,完好的Activity代码如下:
package com.example.materialdemo
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.core.view.GravityCompat
import com.example.materialdemo.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
supportActionBar?.let {
it.setDisplayHomeAsUpEnabled(true)
it.setHomeAsUpIndicator(R.drawable.ic_menu)
}
binding.navView.setCheckedItem(R.id.navCall)
binding.navView.setNavigationItemSelectedListener {
binding.drawerLayout.closeDrawers()
true
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.toolbar, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> binding.drawerLayout.openDrawer(GravityCompat.START)
R.id.backup -> Toast.makeText(this, "You clicked Backup", Toast.LENGTH_SHORT).show()
R.id.delete -> Toast.makeText(this, "You clicked Delete", Toast.LENGTH_SHORT).show()
R.id.settings -> Toast.makeText(this, "You clicked Settings", Toast.LENGTH_SHORT).show()
}
return true
}
}
最终的效果如下:
# 总结 总算把完好的滑动菜单给整出来了,挺有意思,也算是咱们的UI组件学习的第一阶段完毕了。