【Android】Material Design编写更好的UI

Toolbar

对于控件ActionBar我们非常熟悉,就是我们常见的标题栏,但ActionBar只能位于活动的顶部,因此我们更建议使用Toolbar。在新建一个项目的时候都是默认显示ActionBar,我们要使用Toolbar就需要先将标题栏改为不显示

先来看看界面各个部位的属性:

colorAccent:不只用来指定这样一个按钮的颜色,而是更多表达了一个强调的意思,例如一些控件的选中状态也会使用colorAccent的颜色

基本使用:

接下来就看看Toolbar的使用:

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

layout_height:这个属性我们非常熟悉了,但对于后面进行一下解释,?attr/actionBarSize 是一个主题属性引用,它引用了当前主题中定义的 ActionBar 的标准高度

android:theme:将 Toolbar 的主题设置为暗色主题

app:popupTheme:当我们为标题添加菜单按钮的时候按钮也会是暗色的主题,页面就会非常不和谐,因此将标题设置为淡色主题

接下来就看看主活动当中的设置:

java 复制代码
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
    actionBar.setDisplayHomeAsUpEnabled(true); /*actionBar.setHomeAsUpIndicator(R.drawable.ic_launcher_foreground);*/
}

setDisplayHomeAsUpEnabled():设置了 ActionBarhomeAsUp 属性为 truehomeAsUp 属性的作用是让 ActionBar 的左侧显示一个向上导航的按钮(通常是一个箭头图标),点击这个按钮可以触发向上导航的行为。调用这个方法并传入 true 会启用这个按钮。如果用户点击这个按钮,它会调用 onOptionsItemSelected 方法,并传入 android.R.id.home 作为 itemId 参数。你可以在这个方法中处理点击事件,比如导航回上一个 Activity

setHomeAsUpIndicator():就是为这个按钮设置图标,当我们不设置的时候就会使用默认的图标,运行程序,如下图所示:

尝试为左上角的导航按钮注册点击事件,使按下按钮但回到上一个活动:

java 复制代码
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    //android.R.id.home 是 Android 框架中定义的一个资源 ID,它代表了 ActionBar 中的"向上"或"返回首页"按钮的点击事件的ID
    if (item.getItemId() == android.R.id.home) {
        finish();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

添加菜单:

我们先设置一个目录:

xml 复制代码
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/home"
        android:icon="@drawable/ic_launcher_foreground"
        android:title="home"
        app:showAsAction="always"/>

    <item
        android:id="@+id/find"
        android:icon="@drawable/ic_launcher_foreground"
        android:title="find"
        app:showAsAction="ifRoom"/>

    <item
        android:id="@+id/my"
        android:icon="@drawable/ic_launcher_foreground"
        android:title="my"
        app:showAsAction="never"/>
</menu>

将目录加载在Toolbar上:

java 复制代码
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

此时运行程序:

为什么会出现这样的分布,就是我们在设置目录的时候设置的app:showAsAction属性,

app:showAsAction 属性可以设置的一些值及其含义:

  • always : 总是显示在 Toolbar 上。不论 Toolbar 上有多少其他菜单项,这个菜单项都会直接显示在 Toolbar
  • ifRoom : 如果 Toolbar 上有足够空间,就显示在 Toolbar 上。如果空间不足,它会被放置在溢出菜单(Overflow Menu)中
  • never : 从不直接显示在 Toolbar 上,总是位于溢出菜单中

滑动菜单

DrawerLayout

先给大家介绍如何将一个图片设置为圆形,首先需要添加依赖:

apl 复制代码
implementation("de.hdodenhof:circleimageview:3.1.0")
  1. 首先我们制定一个目录,将所有的子目录放在一个group(组)当中,为其设置属性为single
xml 复制代码
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <group android:checkableBehavior="single">
        <item
            android:id="@+id/home1"
            android:icon="@drawable/ic_launcher_foreground"
            android:title="find"/>

        <item
            android:id="@+id/find1"
            android:icon="@drawable/ic_launcher_foreground"
            android:title="find"/>

        <item
            android:id="@+id/my1"
            android:icon="@drawable/ic_launcher_foreground"
            android:title="my"/>
    </group>

</menu>

android:checkableBehavior属性补充:

  1. None : 这是默认值。当设置为 None 时,视图可以独立地被选中或取消选中,不会影响其他具有相同 android:checkable 属性的视图。
  2. Single : 当设置为 Single 时,如果一个视图被选中,其他所有具有相同 android:checkable 属性的视图将自动取消选中。这个行为通常用于单选按钮(RadioButton)组,确保用户在一组选项中只能选择一个。
  3. All : 这个值实际上并不存在于 android:checkableBehavior 属性中。可能是你想要表达的是 Toggle 行为,当设置为 Toggle 时,视图会在被点击时在选中和未选中状态之间切换,这通常用于复选框(CheckBox)
  1. 我们为滑倒出来的布局设置一个头布局:
xml 复制代码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:padding="10dp"
    android:layout_height="match_parent">

    <de.hdodenhof.circleimageview.CircleImageView
        android:id="@+id/iconimg"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:src="@drawable/draw1"
        android:layout_centerInParent="true"/>

    <TextView
        android:id="@+id/mailtext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentBottom="true"
        android:layout_marginStart="10dp"
        android:layout_marginBottom="241dp"
        android:text="123456789@qq.com"
        android:textSize="15sp" />

    <TextView
        android:id="@+id/userText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/iconimg"
        android:layout_alignParentStart="true"
        android:layout_marginStart="20dp"
        android:layout_marginTop="153dp"
        android:gravity="start"
        android:text="自然醒"
        android:textSize="15sp" />

</RelativeLayout>
  1. 修改活动中的布局,将之前的线性布局转换为:
xml 复制代码
<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"
    app:headerLayout="@layout/nav_header"
    app:menu="@menu/nav_menu" />
  1. 此时我们就可以通过向右划动将布局显示出来,修改活动的代码:
java 复制代码
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
//将一开始的选择默认设置为find1
navigationView.setCheckedItem(R.id.find1);
//注册选项的点击事件
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
        drawrLayout.closeDrawers();
        return true;
    }
});

运行程序:

悬浮按钮和可交互提示

FloatingActionButton

这个控件可以轻松的实现悬浮按钮的效果,使用与Button一样

xml 复制代码
<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|end"
    android:layout_margin="30dp"
    android:src="@drawable/draw11"
    //设置悬浮的高度                                                         android:elevation="8dp"/>

SnackBar

在前面我们经常使用Toast来提示用户,但并没有让用户有选择的权力。这个控件就可以让用户可以根据提示进行选择:

java 复制代码
FloatingActionButton floatingActionButton = (FloatingActionButton) findViewById(R.id.fab);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Snackbar.make(v, "data delete", Snackbar.LENGTH_SHORT)
                .setAction("Undo", new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Toast.makeText(DrawrLayout.this, "data restored", Toast.LENGTH_SHORT).show();
                    }
                }).show();
    }
});

此时运行程序:

按下悬浮按钮就会出现提示,无论你是否按下UNDO按钮到时间都会消失,当按下UNDO按钮就会根据我们的代码出现Toast提示。

CoordinatorLayout

相当于一个增强版的Framelayout,可以监听页面的子控件,然后做出合理响应。例如在上面的示例当中,当悬浮窗位于页面的右下角,按下悬浮按钮,提示弹窗弹出的时候就会遮住一部分按钮,看起来体验非常不好,当布局设置为CoordinatorLayout,按下悬浮按钮,提示弹出的时候按钮也会相应的向上移动。

卡片式布局

实际上MaterialCardView也属于FrameLayout,只是额外提供了阴影和圆角等效果。让内容显示在一张卡片当中,拥有圆角和投影

CardView

  1. 先设置RecyclerView子布局:
xml 复制代码
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_margin="5dp"
    app:cardCornerRadius="4dp">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/FruitImage"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:scaleType="centerCrop"/>

        <TextView
            android:id="@+id/FruitText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_margin="5dp"
            android:textSize="16sp"/>

    </LinearLayout>

</com.google.android.material.card.MaterialCardView>
  1. 与RecyclerView的制作一样,运行程序:

文章到这里就结束了!

相关推荐
Ray Liang12 分钟前
用六边形架构与整洁架构对比是伪命题?
java·python·c#·架构设计
Java水解27 分钟前
Java 中间件:Dubbo 服务降级(Mock 机制)
java·后端
砖厂小工2 小时前
用 GLM + OpenClaw 打造你的 AI PR Review Agent — 让龙虾帮你审代码
android·github
张拭心3 小时前
春节后,有些公司明确要求 AI 经验了
android·前端·人工智能
张拭心3 小时前
Android 17 来了!新特性介绍与适配建议
android·前端
SimonKing5 小时前
OpenCode AI辅助编程,不一样的编程思路,不写一行代码
java·后端·程序员
FastBean5 小时前
Jackson View Extension Spring Boot Starter
java·后端
Kapaseker5 小时前
Compose 进阶—巧用 GraphicsLayer
android·kotlin
黄林晴6 小时前
Android17 为什么重写 MessageQueue
android
Seven976 小时前
剑指offer-79、最⻓不含重复字符的⼦字符串
java