一套全新的界面设计语言——Material Design

Toolbor

不仅仅继承了ActionBar的所有功能,而且灵活性很高,可以配合其他控件完成一些Material Design的效果.

任何一个新建的项目都会默认支持ActionBar,他被在AndroidManifest中声明,也就是被定义在了android:theme="@style/AppTheme">主题中。他的默认配置如下:

1
2
3
4
5
6
7
8
9
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>

其中的color是配置颜色的,这有一张颜色配置的图
![](https://image.zfxt.top/hexo-blog/Android入门(Material Design)-2023-08-04-08-42.png)

设置Toolbar

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/design_default_color_primary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
</FrameLayout>

理解一下上述代码的内容。使用了xmlns:app指定了一个新的命名空间,我们就可以使用app:attribute这样的写法了。
但是为什么要加入xmlns:app呢?因为很多Material属性是老系统不存在的,为了能够兼容老系统。就不能使用android:attribute这样的写法了,而是应该使用app:attribute
Toolbar控件,这个控件是由appcompat库提供的。他的theme是为了单独设置toolbar的主题色,浅色或者深色。这里可以设置深色主题,但是如果有菜单按钮,那么弹出的菜单也变成深色,就会变得很难看。所以这里app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>就是设置弹出框为浅色主题

更多功能

  1. 添加按钮
    右击res目录→New→Directory,创建一个menu文件夹。然后右击menu文件夹→New→Menu resource file,创建一个toolbar.xml文件,并编写如下代码:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <?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/loibus10"
    android:title="Backup"
    app:showAsAction="always"/>

    <item
    android:id="@+id/delete"
    android:icon="@drawable/loibus11"
    android:title="Delete"
    app:showAsAction="ifRoom"/>

    <item
    android:id="@+id/settings"
    android:icon="@drawable/loibus12"
    android:title="Settings"
    app:showAsAction="never"/>

    </menu>
    使用app:showAsAction来指定按钮的显示位置,这里之所以再次使用了app命名空间,同样是为了能够兼容低版本的系统。showAsAction主要有以下几种值可选:always表示永远显示在Toolbar中,如果屏幕空间不够则不显示;ifRoom表示屏幕空间足够的情况下显示在Toolbar中,不够的话就显示在菜单当中;never则表示永远显示在菜单当中。注意,Toolbar
    中的action按钮只会显示图标,菜单中的action按钮只会显示文字

    然后再activity中配置按钮的逻辑
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    menuInflater.inflate(R.menu.toolbar, menu)
    return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
    when (item.itemId) {
    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

首先,他是一个布局,在布局中允许放入两个直接子控件:第一个是主屏幕显示的内容。第二个是滑动菜单中显式的内容。
但是关于第二个子控件有一点需要注意,layout_gravity这个属性是必须指定的,因为我们需要告诉DrawerLayout滑动菜单是在屏幕的左边还是右边,指定left表示滑动菜单在左边,指定right表示滑动菜单在右边。指定了start,表示会根据系统语言进行判断,如果系统语言是从左往右的,比如英语、汉语,滑动菜单就在左边,如果系统语言是从右往左的,比如阿拉伯语,滑动菜单就在右边。

1
2
3
4
5
setSupportActionBar(binding.toolbar)
supportActionBar?.let {
it.setDisplayHomeAsUpEnabled(true)
it.setHomeAsUpIndicator(R.drawable.loibus16)
}

这一段代码的作用是在ActionBar不为空的情况下调用setDisplayHomeAsUpEnabled()方法让导航按钮显示出来,调用setHomeAsUpIndicator()方法来设置一个导航按钮图标。
实际上,ToolBar最左侧的按钮被称为Home按钮,默认为一个返回的箭头,作用是返回上一个activity。而且这给按钮的id永远是android.R.id.home,这是系统内定的,我们在为其设置相应的逻辑android.R.id.home->binding.drawerLayout.openDrawer(GravityCompat.START)

可以在滑动菜单页面定制任意的布局。
他需要再导入两个包,

1
2
3
4
//Material库
implementation("com.google.android.material:material:1.9.0")
//开源项目CircleImageView,它可以用来轻松实现图片圆形化的功能
implementation("de.hdodenhof:circleimageview:3.0.1")

需要注意的是,当你引入了Material库之后,还需要将res/values/styles.xml文件中AppTheme的parent主题改成Theme.MaterialComponents.Light.NoActionBar,否则在使用接下来的一些控件时可能会遇到崩溃问题。

使用NavigationView,要准备好menu和headerLayout。前者是用来再NavigationView显示菜单项的,后者是用来在NavigationView定义头部的

1
2
3
4
5
6
7
<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"/>

这是为Drawerlayout配置NavigationView,其中声明好了menu和headerLayout。
配置menu时,需要注意的是

1
2
3
<group android:checkableBehavior="single">
...
</group>

这里的配置表明只能单选。
最后在activity中配置

1
2
3
4
5
binding.navView.setCheckedItem(R.id.navCall)
binding.navView.setNavigationItemSelectedListener {
binding.drawerLayout.closeDrawers()
true
}

这里先设置了默认选择项,然后配置他们所有选项的逻辑。这里所有的逻辑都是关闭滑动菜单

还有很多特性,不一一列举,看过一遍就不再记笔记了。这些都可以网上轻松找到代码

  1. 悬浮按钮(FloatingActionButton)

  2. 可交互提示Snackbar

  3. CoordinatorLayout(加强版的FrameLayout)

CoordinatorLayout可以监听其所有子控件的各种事件,并自动帮助我们做出最为合理的响应。举个简单的例子,刚才弹出的Snackbar提示将悬浮按钮遮挡住了,而如果我们能让CoordinatorLayout监听到Snackbar的弹出事件,那么它会自动将内部的
FloatingActionButton向上偏移,从而确保不会被Snackbar遮挡。

  1. glide
    implementation 'com.github.bumptech.glide:glide:4.9.0'
    Glide是一个超级强大的开源图片加载库,它不仅可以用于加载本地图片,还可以加载网络图片、GIF图片甚至是本地视频。
    而且Glide的用法很简单。首先调用Glide.with()方法并传入一个Context、Activity或Fragment参数,然后调用load()方法加载图片,可以是一个URL地址,也可以是一个本地路径,或者是一个资源id,最后调用into()方法将图片设置到具体某一个ImageView中就可以了。

  2. 卡片式布局(MaterialCardView)

  3. ImageView中我们使用了一个scaleType属性,这个属性可以指定图片的缩放模式。

  4. 为了让所有的图片都能填充满整个ImageView,这里使用了centerCrop模式,它可以让图片保持原有比例填充满ImageView,并将超出屏幕的部分裁剪掉

  5. AppBarLayout,与app:layout_behavior指定布局appbar_scrolling_view_behavior。相互配合。
    app:layout_scrollFlags在Toolbar中添加了一个app:layout_scrollFlags属性,并将这个属性的值指定成了scroll|enterAlways|snap。其中,scroll表示当RecyclerView向上滚动的时候,Toolbar会跟着一起向上滚动并实现隐藏;enterAlways表示当RecyclerView向下滚动的时候,Toolbar会跟着一起向下滚动并重新显示;snap表示当Toolbar还没有完全隐藏或显示的时候,会根据当前滚动的距离,自动选择是隐藏还是显示。

  6. 下拉刷新,首先需要导入相关的类implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
    通过这个类。。只要在需要设置刷新的模块上套上一层swiperefreshlayout就可以实现下拉功能。然后我们需要在activity中设置他的逻辑功能。

  7. 可折叠式标题栏(CollapsingToolbarLayout)