Android学习之Material Components

以下是 Material Design 提供的核心控件列表(基于最新 Material Components for Android 库),按功能分类整理:


1. 基础按钮类

控件名称类名说明
MaterialButtoncom.google.android.material.button.MaterialButton遵循 Material 规范的按钮,支持圆角、阴影等
FloatingActionButtoncom.google.android.material.floatingactionbutton.FloatingActionButton悬浮操作按钮,用于主要操作
TextButtoncom.google.android.material.button.TextButton无边界的纯文本按钮
OutlinedButtoncom.google.android.material.button.OutlinedButton带边框的轮廓按钮

2. 表单与输入控件

控件名称类名说明
TextInputLayoutcom.google.android.material.textfield.TextInputLayout包裹 TextInputEditText 的容器,支持标签动画
TextInputEditTextcom.google.android.material.textfield.TextInputEditText带输入验证和错误提示的 EditText
Switchcom.google.android.material.materialswitch.MaterialSwitch开关控件(Material 风格)
Checkboxcom.google.android.material.checkbox.MaterialCheckBox复选框
RadioButtoncom.google.android.material.radiobutton.MaterialRadioButton单选按钮
AutoCompleteTextViewcom.google.android.material.textfield.MaterialAutoCompleteTextView带自动补全功能的输入框

3. 导航与布局

控件名称类名说明
BottomNavigationViewcom.google.android.material.bottomnavigation.BottomNavigationView底部导航栏,支持标签切换
NavigationViewcom.google.android.material.navigation.NavigationView侧边栏导航菜单(搭配 DrawerLayout 使用)
TabLayoutcom.google.android.material.tabs.TabLayout标签页布局,常与 ViewPager 结合使用
BottomAppBarcom.google.android.material.bottomappbar.BottomAppBar底部应用栏,常与 FloatingActionButton 结合

4. 信息展示

控件名称类名说明
CardViewcom.google.android.material.card.MaterialCardView带圆角和阴影的卡片容器
Snackbarcom.google.android.material.snackbar.Snackbar短暂提示栏,显示操作反馈
Dividercom.google.android.material.divider.MaterialDivider分割线控件
ProgressBarcom.google.android.material.progressindicator.LinearProgressIndicator线性进度条(替代旧版 ProgressBar)

5. 对话框与弹窗

控件名称类名说明
MaterialAlertDialogMaterialAlertDialogBuilder (通过 Builder 创建)响应式对话框
BottomSheetDialogcom.google.android.material.bottomsheet.BottomSheetDialog底部弹出式对话框

6. 其他组件

控件名称类名说明
Chipcom.google.android.material.chip.Chip标签组件,用于分类或选择
MenuMaterialMenuItem (通过 XML 定义)菜单项(需配合 MenuInflater 使用)
DatePickercom.google.android.material.datepicker.MaterialDatePicker日期选择器
TimePickercom.google.android.material.timepicker.MaterialTimePicker时间选择器

使用说明

  1. 依赖版本

    implementation 'com.google.android.material:material:1.9.0'  // 使用最新稳定版本
    
  2. 核心特性

    • 所有控件均遵循 Material Design 3 (MD3) 规范(如 MaterialButton 的形状、阴影、颜色主题等)。
    • 支持动态主题(通过 Theme.MaterialComponents 系列主题)。
    • 提供丰富的属性配置(如 app:shapeAppearanceapp:rippleColor 等)。
  3. 注意事项

    • 部分旧版控件(如 FloatingActionButton)在 Material Components 中重新设计,需注意迁移。
    • 需要 API 14+ 以上支持,但可通过 AppCompat 兼容更早版本。

实践与对比

按钮

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 普通 Button 示例 -->
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:text="Standard Button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <!-- MaterialButton 示例 -->
    <com.google.android.material.button.MaterialButton
        android:id="@+id/material_button"
        style="@style/Widget.MaterialComponents.Button.OutlinedButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="Material Button"
        android:textColor="@color/white"
        app:backgroundTint="?attr/colorPrimary"
        app:cornerRadius="8dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/button"
        app:rippleColor="?attr/colorOnPrimary"
        app:strokeColor="?attr/colorPrimary"
        app:strokeWidth="2dp"
        app:textColor="@android:color/white" />

    <!--  FloatingActionButton  -->
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/floating_action_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        app:backgroundTint="?attr/colorPrimary"
        app:elevation="6dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:pressedTranslationZ="12dp"
        app:srcCompat="@android:drawable/ic_menu_add" />
</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述

特点对比

控件特点
普通 Button原生基础控件,样式简单(矩形无圆角),无 Material 特性(如涟漪效果),依赖系统主题。
MaterialButton支持 Material Design 风格(圆角、边框、填充/轮廓/文字样式),动态主题适配,涟漪反馈。
FloatingActionButton圆形图标按钮,用于核心操作,悬浮定位(如右下角),自带阴影和 Z 轴交互反馈。

使用场景对比

控件适用场景
普通 Button简单交互(如表单提交)、无需 Material 风格、低版本兼容场景。
MaterialButton需要 Material 设计语言(圆角/边框/主题适配)、复杂视觉反馈(如电商按钮、设置项)。
FloatingActionButton突出核心操作(如“添加”“新建”),需固定在屏幕边缘,配合 Material 主题使用。

核心对比表格

维度普通 ButtonMaterialButtonFloatingActionButton
核心用途简单交互Material 风格按钮突出核心操作的悬浮按钮
样式复杂度简单(矩形无装饰)高(圆角/边框/填充/轮廓)高(圆形图标+阴影)
图标支持仅文字(需自定义图标)支持文字+图标(需配置)强制图标(无文字)
主题适配系统主题动态主题(如深色模式)动态主题(颜色/阴影跟随主题)
定位方式需手动布局需手动布局通常固定屏幕边缘(如右下角)
依赖库com.google.android.material同 MaterialButton
交互反馈无涟漪效果支持涟漪效果支持 Z 轴按下偏移

选择总结

  • 选普通 Button:简单需求、无需 Material 风格。
  • 选 MaterialButton:需要 Material 视觉(圆角/边框/主题适配)。
  • 选 FloatingActionButton:需突出核心操作(如“+”按钮)。

输入控件

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <!-- 普通 EditText 示例 -->
    <EditText
        android:id="@+id/et_input"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:background="@android:drawable/editbox_background"
        android:hint="普通输入框"
        android:textColorHint="#666"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <!-- Material Design 输入框 -->
    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/username_layout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        app:boxBackgroundColor="#FFF"
        app:boxStrokeColor="?attr/colorPrimary"
        app:boxBackgroundMode="outline"
        app:errorEnabled="true"
        app:helperText="Material Design 输入框"
        app:helperTextTextColor="?attr/colorPrimary"
        app:startIconDrawable="@drawable/ic_launcher_foreground"
        app:endIconMode="clear_text"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/et_input"
        app:layout_constraintBottom_toBottomOf="parent">

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/username_input"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="用户名"
            android:inputType="text"
            android:textColor="?attr/colorOnSurface" />
    </com.google.android.material.textfield.TextInputLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述

特点对比

控件特点
普通 EditText原生基础输入框,样式简单(下划线/矩形边框),无 Material 特性(如浮动标签/图标支持),依赖系统主题。
TextInputLayout + EditText仅实现容器包裹样式,缺少 Material Design 规范特性(如动态颜色适配/图标交互反馈)。
TextInputLayout + TextInputEditText完整 Material Design 输入组件,支持浮动标签、错误提示、图标系统、动态主题适配,提供交互反馈。

使用场景对比

控件适用场景
普通 EditText简单输入场景(如快速原型开发)、无需 Material 风格、低版本兼容需求。
TextInputLayout + EditText过渡方案(已有 EditText 改造),需要部分 Material 容器样式但无需完整特性。
TextInputLayout + TextInputEditText规范 Material 设计场景(如登录表单)、需要错误提示/图标交互/主题适配等高级功能。

核心对比表格

维度普通 EditTextTextInputLayout+EditTextTextInputLayout+TextInputEditText
浮动标签动画❌ 不支持❌ 需手动实现✅ 自动浮动/收缩动画
图标系统❌ 仅自定义实现⚠️ 部分支持(需手动适配)✅ 完整支持(start/end icon 体系)
错误提示机制❌ 需自定义⚠️ 基础提示(无动画)✅ 带动画的错误提示+辅助计数器
主题适配系统主题颜色需硬编码✅ 动态适配(?attr/colorPrimary 等)
辅助功能基础 Accessibility需手动添加 ContentDescription✅ 自动适配 TalkBack
依赖库com.google.android.material同左

选择总结

  • 选普通 EditText:快速验证功能原型、非 Material 设计场景
  • 选 TextInputLayout+TextInputEditText
    • 需要完整的 Material Design 输入体验
    • 要求自动主题适配(深色模式切换)
    • 需要标准化错误提示/图标交互

开关

<?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"
    android:background="#FAFAFA"
    android:padding="24dp">

    <!-- 标题 -->
    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Switch 控件对比"
        android:textSize="20sp"
        android:textColor="#333333"
        android:textStyle="bold"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_marginBottom="24dp"/>

    <!-- 普通Switch控件区域 -->
    <TextView
        android:id="@+id/default_switch_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="默认 Switch 控件"
        android:textSize="16sp"
        android:textColor="#555555"
        app:layout_constraintTop_toBottomOf="@id/title"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginBottom="16dp"/>

    <LinearLayout
        android:id="@+id/default_switches"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center"
        android:layout_marginBottom="32dp"
        app:layout_constraintTop_toBottomOf="@id/default_switch_label">
        <Switch
            android:id="@+id/switch1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="开关1"
            android:textColor="#333333"
            android:layout_marginEnd="32dp"/>

        <Switch
            android:id="@+id/switch2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="开关2"
            android:checked="true"
            android:textColor="#333333"/>
    </LinearLayout>

    <!-- Material风格Switch控件区域 -->
    <TextView
        android:id="@+id/material_switch_label"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Material Switch 控件"
        android:textSize="16sp"
        android:textColor="#555555"
        app:layout_constraintTop_toBottomOf="@id/default_switches"
        app:layout_constraintStart_toStartOf="parent"
        android:layout_marginBottom="16dp"/>

    <LinearLayout
        android:id="@+id/material_switches"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center"
        app:layout_constraintTop_toBottomOf="@id/material_switch_label">

        <com.google.android.material.switchmaterial.SwitchMaterial
            android:id="@+id/material_switch1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Material开关1"
            android:textColor="#333333"
            android:layout_marginEnd="32dp"
            app:useMaterialThemeColors="true"/>

        <com.google.android.material.switchmaterial.SwitchMaterial
            android:id="@+id/material_switch2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Material开关2"
            android:textColor="#333333"
            android:checked="true"
            app:useMaterialThemeColors="true"/>
    </LinearLayout>
    

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述

特点对比

控件特点
普通 Switch原生基础控件,样式简单(直角滑块/无主题适配),无 Material 特性(如动态颜色/涟漪效果)。
SwitchMaterial支持 Material Design 规范(圆角滑块/动态主题),提供图标支持、触摸涟漪反馈、无障碍优化。

使用场景对比

控件适用场景
普通 Switch简单开关功能、无需 Material 风格、兼容低版本 Android 系统(API < 21)。
SwitchMaterial需要 Material 设计语言(如深色模式适配)、更流畅的交互反馈、图标自定义需求。

核心对比表格

维度普通 SwitchSwitchMaterial
样式直角滑块+灰色轨道圆角滑块+主题色轨道
主题适配依赖系统主题动态适配 ?attr/colorPrimary 等属性
图标支持❌ 仅文字✅ 支持 app:thumbIconapp:trackIcon
交互反馈基础按压效果涟漪动画 + 按压 Z 轴抬升效果
无障碍支持基础 TalkBack自动适配内容描述(ContentDescription)
依赖库com.google.android.material
自定义属性有限(仅基础颜色/文本)支持滑块尺寸、图标资源、轨道颜色等

XML 属性对比示例

<!-- 普通 Switch 的典型实现 -->
<Switch
    android:thumbTint="#FF4081"      <!-- 固定颜色 -->
    android:trackTint="#BDBDBD" />   <!-- 无主题适配 -->

<!-- Material Switch 的规范实现 -->
<com.google.android.material.switchmaterial.SwitchMaterial
    app:thumbTint="?attr/colorPrimary"           <!-- 动态主题色 -->
    app:trackColor="?attr/colorSurfaceVariant"   <!-- 轨道主题色 -->
    app:thumbIcon="@drawable/ic_custom_thumb"    <!-- 自定义滑块图标 -->
    app:rippleColor="?attr/colorOnPrimary" />    <!-- 涟漪效果颜色 -->

选择总结

  • 选普通 Switch

    • 项目需兼容 Android 4.x 及以下版本
    • 快速原型开发,无需复杂样式
  • 选 SwitchMaterial

    • 遵循 Material Design 规范(如深色模式适配)
    • 需要动态主题色或自定义图标
    • 要求更好的交互反馈(如涟漪效果)

选择器

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FAFAFA"
    android:padding="16dp">

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

        <!-- 复选框对比部分 -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="CheckBox 对比"
            android:textSize="18sp"
            android:textColor="#333333"
            android:textStyle="bold"
            android:layout_marginBottom="16dp"/>

        <!-- 普通CheckBox -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="普通CheckBox"
            android:textSize="14sp"
            android:textColor="#555555"
            android:layout_marginBottom="8dp"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginBottom="24dp">

            <CheckBox
                android:id="@+id/normal_checkbox1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="选项1"
                android:layout_marginEnd="24dp"/>

            <CheckBox
                android:id="@+id/normal_checkbox2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="true"
                android:text="选项2"/>
        </LinearLayout>

        <!-- MaterialCheckBox -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="MaterialCheckBox"
            android:textSize="14sp"
            android:textColor="#555555"
            android:layout_marginBottom="8dp"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginBottom="32dp">

            <com.google.android.material.checkbox.MaterialCheckBox
                android:id="@+id/material_checkbox1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="选项1"
                app:useMaterialThemeColors="true"
                android:layout_marginEnd="24dp"/>

            <com.google.android.material.checkbox.MaterialCheckBox
                android:id="@+id/material_checkbox2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="选项2"
                android:checked="true"
                app:useMaterialThemeColors="true"/>
        </LinearLayout>

        <!-- 分割线 -->
        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#E0E0E0"
            android:layout_marginVertical="8dp"/>

        <!-- 单选按钮对比部分 -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="RadioButton 对比"
            android:textSize="18sp"
            android:textColor="#333333"
            android:textStyle="bold"
            android:layout_marginBottom="16dp"/>

        <!-- 普通RadioButton -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="普通RadioButton"
            android:textSize="14sp"
            android:textColor="#555555"
            android:layout_marginBottom="8dp"/>

        <RadioGroup
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginBottom="24dp">

            <RadioButton
                android:id="@+id/normal_radio1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="选项A"
                android:layout_marginEnd="24dp"/>

            <RadioButton
                android:id="@+id/normal_radio2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:checked="true"
                android:text="选项B"/>
        </RadioGroup>

        <!-- MaterialRadioButton -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="MaterialRadioButton"
            android:textSize="14sp"
            android:textColor="#555555"
            android:layout_marginBottom="8dp"/>

        <RadioGroup
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginBottom="24dp">

            <com.google.android.material.radiobutton.MaterialRadioButton
                android:id="@+id/material_radio1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="选项A"
                app:useMaterialThemeColors="true"
                android:layout_marginEnd="24dp"/>

            <com.google.android.material.radiobutton.MaterialRadioButton
                android:id="@+id/material_radio2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="选项B"
                android:checked="true"
                app:useMaterialThemeColors="true"/>
        </RadioGroup>

    </LinearLayout>
</ScrollView>

CheckBox 对比分析


特点对比
控件特点
普通 CheckBox原生基础控件,样式简单(方框勾选),无 Material 特性(如动态颜色/涟漪效果),依赖系统主题
MaterialCheckBox支持 Material Design 规范(动态颜色/动画过渡),提供触摸涟漪反馈、主题自动适配能力

使用场景对比
控件适用场景
普通 CheckBox简单选择场景、低版本兼容需求(API < 21)、无需主题适配
MaterialCheckBox需要 Material 设计语言、深色模式支持、动态主题色适配场景

核心对比表格
维度普通 CheckBoxMaterialCheckBox
选中动画❌ 无过渡动画✅ 缩放+颜色渐变动画
主题适配固定颜色需硬编码自动适配 ?attr/colorPrimary
错误状态显示❌ 需自定义实现✅ 内置错误状态样式
无障碍支持基础 TalkBack✅ 自动生成内容描述
触摸反馈基础按压效果✅ 涟漪动画反馈
自定义属性仅基础颜色/尺寸支持图标/波纹颜色/状态指示器等

RadioButton 对比分析


特点对比
控件特点
普通 RadioButton原生单选控件,样式传统(圆形外框),无动态主题适配能力
MaterialRadioButton符合 Material 规范(动态波浪效果),支持主题色自动适配和触摸反馈优化

使用场景对比
控件适用场景
普通 RadioButton基础单选需求、兼容旧版本系统(API < 21)
MaterialRadioButton需要 Material 交互动画、主题色动态切换的场景

核心对比表格
维度普通 RadioButtonMaterialRadioButton
选择动画❌ 瞬间切换✅ 波浪扩散动画
主题颜色适配需手动设置颜色自动继承 colorSecondary
禁用状态显示❌ 灰显效果单一✅ 带透明度变化的禁用状态
触摸区域仅图标区域可点击✅ 文本标签联动点击
自定义能力仅支持基础属性支持按钮尺寸/波纹颜色/图标等

综合对比说明

<!-- Material 组件正确使用示例 -->
<com.google.android.material.checkbox.MaterialCheckBox
    android:text="选项1"
    app:buttonTint="?attr/colorSecondary"
    app:useMaterialThemeColors="true"
    app:rippleColor="@color/ripple_color"/>

<com.google.android.material.radiobutton.MaterialRadioButton
    android:text="选项A"
    app:buttonTint="?attr/colorPrimary"
    app:useMaterialThemeColors="true"/>

选择建议

  1. 选用普通组件的情况

    • 需要支持 Android 4.x 及以下系统
    • 项目时间紧张只需实现基础功能
    • 示例:<CheckBox android:text="基础选项"/>
  2. 必须使用 Material 组件的情况

    • 要求符合 Material Design 规范
    • 需要深色模式自动适配
    • 需要交互动画提升用户体验
    • 示例:<MaterialCheckBox app:useMaterialThemeColors="true"/>

主题配置提醒

使用 Material 组件时,请确保应用主题继承自 MaterialComponents:

<!-- res/values/themes.xml -->
<style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight">
    <item name="colorPrimary">@color/purple_500</item>
    <item name="colorSecondary">@color/pink_200</item>
    <item name="colorSurface">@color/white</item>
</style>

导航与布局实现详解

这部分图就不放了,建议复制代码实际上手体验一下各个布局


1. BottomNavigationView(底部导航栏)

功能特点

  • 固定3-5个导航标签
  • 支持图标和文字组合
  • 内置平滑过渡动画

实现步骤

  1. 布局文件 (activity_main.xml)
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 主内容区 -->
    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@id/bottom_nav"
        app:layout_constraintTop_toTopOf="parent"/>

    <!-- 底部导航栏 -->
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:labelVisibilityMode="labeled"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:menu="@menu/bottom_nav_menu"/>

</androidx.constraintlayout.widget.ConstraintLayout>
  1. 菜单配置 (res/menu/bottom_nav_menu.xml)
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/nav_home"
          android:icon="@drawable/ic_home"
          android:title="首页"/>
    <item android:id="@+id/nav_search"
          android:icon="@drawable/ic_search"
          android:title="搜索"/>
    <item android:id="@+id/nav_profile"
          android:icon="@drawable/ic_person"
          android:title="我的"/>
</menu>
  1. 交互处理 (Activity/Fragment中)
bottom_nav.setOnItemSelectedListener { item ->
    when(item.itemId) {
        R.id.nav_home -> showFragment(HomeFragment())
        R.id.nav_search -> showFragment(SearchFragment())
        R.id.nav_profile -> showFragment(ProfileFragment())
    }
    true
}

2. NavigationView(侧边导航抽屉)

功能特点

  • 必须配合DrawerLayout使用
  • 支持自定义头部布局
  • 可分组显示菜单项

实现步骤

  1. 主布局结构 (activity_main.xml)
<androidx.drawerlayout.widget.DrawerLayout
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <!-- 主内容 -->
    <include layout="@layout/content_main"/>

    <!-- 导航抽屉 -->
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/nav_header"
        app:menu="@menu/nav_menu"/>
</androidx.drawerlayout.widget.DrawerLayout>
  1. 头部布局 (res/layout/nav_header.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="180dp"
    android:background="@color/colorPrimary"
    android:orientation="vertical"
    android:padding="16dp">

    <ImageView
        android:layout_width="72dp"
        android:layout_height="72dp"
        android:src="@drawable/ic_logo"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="应用名称"
        android:textColor="@android:color/white"
        android:textSize="18sp"/>
</LinearLayout>
  1. 菜单配置 (res/menu/nav_menu.xml)
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item android:id="@+id/nav_home"
              android:icon="@drawable/ic_home"
              android:title="首页"/>
        <item android:id="@+id/nav_gallery"
              android:icon="@drawable/ic_photo"
              android:title="相册"/>
    </group>
    
    <item android:title="设置">
        <menu>
            <item android:id="@+id/nav_settings"
                  android:icon="@drawable/ic_settings"
                  android:title="系统设置"/>
        </menu>
    </item>
</menu>

3. TabLayout(标签页导航)

功能特点

  • 支持固定/滚动模式
  • 与ViewPager2完美配合
  • 自定义指示器样式

实现步骤

  1. 布局文件 (activity_tabs.xml)
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:tabIndicatorAnimationMode="elastic"
            app:tabMode="fixed"/>

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

</LinearLayout>
  1. 适配器实现
class TabPagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) {
    override fun getItemCount() = 3

    override fun createFragment(position: Int) = when(position) {
        0 -> NewsFragment()
        1 -> SportsFragment()
        else -> TechFragment()
    }
}
  1. 关联Tab与ViewPager
val tabLayout = findViewById<TabLayout>(R.id.tabs)
val viewPager = findViewById<ViewPager2>(R.id.view_pager)

viewPager.adapter = TabPagerAdapter(this)

TabLayoutMediator(tabLayout, viewPager) { tab, position ->
    tab.text = when(position) {
        0 -> "新闻"
        1 -> "体育"
        else -> "科技"
    }
}.attach()

4. BottomAppBar(底部应用栏)

功能特点

  • 支持嵌入FAB按钮
  • 可定制导航菜单
  • 多种裁剪形状可选

实现步骤

  1. 布局文件 (activity_appbar.xml)
<androidx.coordinatorlayout.widget.CoordinatorLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!-- 主内容 -->
    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <!-- 底部应用栏 -->
    <com.google.android.material.bottomappbar.BottomAppBar
        android:id="@+id/bottom_appbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:layout_gravity="bottom"
        app:fabCradleMargin="8dp"
        app:fabCradleRoundedCornerRadius="8dp"
        app:navigationIcon="@drawable/ic_menu">

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:menu="@menu/bottom_appbar_menu"/>
    </com.google.android.material.bottomappbar.BottomAppBar>

    <!-- 悬浮按钮 -->
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_add"
        app:layout_anchor="@id/bottom_appbar"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
  1. 交互处理
bottom_appbar.setNavigationOnClickListener {
    // 处理导航点击
}

fab.setOnClickListener {
    // 处理FAB点击
}

信息展示控件对比实现


1. CardView 对比

MaterialCardView vs 普通CardView

<?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"
    android:padding="16dp">

    <!-- MaterialCardView实现 -->
    <com.google.android.material.card.MaterialCardView
        android:id="@+id/materialCardView"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:layout_margin="16dp"
        app:cardCornerRadius="8dp"
        app:cardElevation="4dp"
        app:strokeColor="@color/purple_500"
        app:strokeWidth="1dp"
        app:layout_constraintTop_toTopOf="parent"
        tools:layout_editor_absoluteX="32dp"
        tools:layout_editor_absoluteY="16dp">

        <!-- 卡片内容 -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="MaterialCardView"
            android:textSize="18sp" />

    </com.google.android.material.card.MaterialCardView>

    <!-- 普通CardView实现 -->
    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:layout_margin="16dp"
        app:cardCornerRadius="8dp"
        app:cardElevation="4dp"
        app:layout_constraintBottom_toBottomOf="parent"
        tools:layout_editor_absoluteX="32dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="普通CardView"
            android:textSize="18sp" />

    </androidx.cardview.widget.CardView>

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述

对比特性

特性MaterialCardView普通CardView
边框描边✅ 支持❌ 不支持
动态主题适配✅ 自动适配深色模式❌ 需手动配置
波纹点击效果✅ 默认启用❌ 需自定义
检查器模式✅ 支持(app:checked)❌ 不支持

2. Snackbar 对比

Material Snackbar vs 原生Toast

// Material Snackbar实现
Snackbar.make(view, "操作已保存", Snackbar.LENGTH_LONG)
    .setAction("撤销") { /* 撤销操作 */ }
    .setBackgroundTint(ContextCompat.getColor(this, R.color.purple_500))
    .show()

// 原生Toast实现
Toast.makeText(this, "操作已保存", Toast.LENGTH_LONG).show()

对比特性

特性Material Snackbar原生Toast
交互动作按钮✅ 支持❌ 不支持
位置控制✅ 可锚定到指定视图下方❌ 固定屏幕位置
主题适配✅ 自动适配❌ 系统默认样式
显示时长✅ LENGTH_SHORT/LONG✅ 同左
队列管理✅ 自动排队显示❌ 会立即覆盖前一条

3. Divider 对比

MaterialDivider vs View分割线

<?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"
    android:padding="16dp">

    <!-- MaterialDivider实现 -->
    <com.google.android.material.divider.MaterialDivider
        android:id="@+id/divider"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginVertical="8dp"
        app:dividerColor="@color/purple_500"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/view2"
        app:dividerThickness="2dp"/>

    <!-- 普通View实现 -->
    <View
        android:id="@+id/view2"
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_marginVertical="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/divider"
        android:background="#CCC"/>

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述

对比特性

特性MaterialDivider普通View
粗细控制✅ app:dividerThickness❌ 需手动设置高度
颜色透明度✅ 自动处理❌ 需手动配置
方向控制✅ 水平/垂直❌ 需旋转布局
主题适配✅ 自动适配❌ 固定颜色

4. ProgressBar 对比

这个最好也自己写个demo体验一下,主要就优化了动画

LinearProgressIndicator vs 普通ProgressBar

<!-- Material进度条 -->
<com.google.android.material.progressindicator.LinearProgressIndicator
    android:id="@+id/material_progress"
    android:layout_width="match_parent"
    android:layout_height="4dp"
    app:indicatorColor="@color/purple_500"
    app:trackColor="@color/gray_light"
    app:indeterminateAnimationType="contiguous"/>

<!-- 普通进度条 -->
<ProgressBar
    android:id="@+id/default_progress"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="match_parent"
    android:layout_height="4dp"
    android:progressDrawable="@drawable/custom_progress"/>

对比特性

特性LinearProgressIndicator普通ProgressBar
动画类型✅ 4种预设动画模式❌ 需自定义
轨道颜色✅ 单独控制❌ 需自定义drawable
主题适配✅ 自动适配❌ 固定样式
不确定模式✅ 平滑动画❌ 卡顿明显
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值