Flutter AppBar 导航栏组件完全指南

什么是 AppBar?

AppBar 是 Flutter 中的顶部导航栏组件,通常放在 Scaffold 的 appBar 属性中。

用途:

  • 显示页面标题
  • 返回按钮
  • 操作按钮
  • 搜索功能
  • 标签切换

基础用法

dart 复制代码
Scaffold(
  appBar: AppBar(
    title: Text('标题'),
  ),
  body: Container(),
)

常用属性

1. title - 标题

dart 复制代码
AppBar(
  title: Text('我的应用'),
)

2. leading - 左侧组件

dart 复制代码
AppBar(
  leading: IconButton(
    icon: Icon(Icons.menu),
    onPressed: () {},
  ),
  title: Text('标题'),
)

3. actions - 右侧操作按钮

dart 复制代码
AppBar(
  title: Text('标题'),
  actions: [
    IconButton(
      icon: Icon(Icons.search),
      onPressed: () {},
    ),
    IconButton(
      icon: Icon(Icons.more_vert),
      onPressed: () {},
    ),
  ],
)

4. backgroundColor - 背景颜色

dart 复制代码
AppBar(
  title: Text('标题'),
  backgroundColor: Colors.blue,
)

5. centerTitle - 标题居中

dart 复制代码
AppBar(
  title: Text('标题'),
  centerTitle: true,  // 标题居中
)

6. elevation - 阴影高度

dart 复制代码
AppBar(
  title: Text('标题'),
  elevation: 0,  // 无阴影
)

7. bottom - 底部组件

dart 复制代码
AppBar(
  title: Text('标题'),
  bottom: TabBar(
    tabs: [
      Tab(text: '标签1'),
      Tab(text: '标签2'),
      Tab(text: '标签3'),
    ],
  ),
)

实战案例

案例1:基础导航栏

dart 复制代码
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: BasicAppBarPage(),
    );
  }
}

class BasicAppBarPage extends StatelessWidget {
  const BasicAppBarPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('首页'),
        centerTitle: true,
        leading: IconButton(
          icon: const Icon(Icons.menu),
          onPressed: () {
            print('打开菜单');
          },
        ),
        actions: [
          IconButton(
            icon: const Icon(Icons.search),
            onPressed: () {
              print('搜索');
            },
          ),
          IconButton(
            icon: const Icon(Icons.notifications),
            onPressed: () {
              print('通知');
            },
          ),
        ],
      ),
      body: const Center(child: Text('基础导航栏示例')),
    );
  }
}

案例2:渐变导航栏

dart 复制代码
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: GradientAppBarPage(),
    );
  }
}

class GradientAppBarPage extends StatelessWidget {
  const GradientAppBarPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('渐变导航栏'),
        centerTitle: true,
        flexibleSpace: Container(
          decoration: const BoxDecoration(
            gradient: LinearGradient(
              colors: [Colors.blue, Colors.purple],
              begin: Alignment.topLeft,
              end: Alignment.bottomRight,
            ),
          ),
        ),
      ),
      body: const Center(child: Text('渐变导航栏示例')),
    );
  }
}

案例3:透明导航栏

dart 复制代码
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: TransparentAppBarPage(),
    );
  }
}

class TransparentAppBarPage extends StatelessWidget {
  const TransparentAppBarPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      extendBodyBehindAppBar: true,
      appBar: AppBar(
        title: const Text('透明导航栏'),
        backgroundColor: Colors.transparent,
        elevation: 0,
      ),
      body: Container(
        decoration: const BoxDecoration(
          image: DecorationImage(
            image: NetworkImage('https://picsum.photos/400/800'),
            fit: BoxFit.cover,
          ),
        ),
      ),
    );
  }
}

案例4:搜索导航栏

dart 复制代码
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: SearchAppBar(),
    );
  }
}

class SearchAppBar extends StatefulWidget {
  const SearchAppBar({Key? key}) : super(key: key);

  @override
  State<SearchAppBar> createState() => _SearchAppBarState();
}

class _SearchAppBarState extends State<SearchAppBar> {
  bool _isSearching = false;
  final TextEditingController _searchController = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: _isSearching
            ? TextField(
                controller: _searchController,
                autofocus: true,
                decoration: const InputDecoration(
                  hintText: '搜索...',
                  border: InputBorder.none,
                  hintStyle: TextStyle(color: Colors.white70),
                ),
                style: const TextStyle(color: Colors.white),
                onSubmitted: (value) {
                  print('搜索: $value');
                },
              )
            : const Text('搜索示例'),
        actions: [
          IconButton(
            icon: Icon(_isSearching ? Icons.close : Icons.search),
            onPressed: () {
              setState(() {
                _isSearching = !_isSearching;
                if (!_isSearching) {
                  _searchController.clear();
                }
              });
            },
          ),
        ],
      ),
      body: const Center(child: Text('内容')),
    );
  }

  @override
  void dispose() {
    _searchController.dispose();
    super.dispose();
  }
}

案例5:带 TabBar 的导航栏

dart 复制代码
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: TabBarPage(),
    );
  }
}

class TabBarPage extends StatelessWidget {
  const TabBarPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('标签页'),
          bottom: const TabBar(
            tabs: [
              Tab(icon: Icon(Icons.home), text: '首页'),
              Tab(icon: Icon(Icons.explore), text: '发现'),
              Tab(icon: Icon(Icons.person), text: '我的'),
            ],
          ),
        ),
        body: const TabBarView(
          children: [
            Center(child: Text('首页')),
            Center(child: Text('发现')),
            Center(child: Text('我的')),
          ],
        ),
      ),
    );
  }
}

案例6:可滚动的 AppBar

dart 复制代码
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: ScrollableAppBarPage(),
    );
  }
}

class ScrollableAppBarPage extends StatelessWidget {
  const ScrollableAppBarPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: [
          SliverAppBar(
            expandedHeight: 200,
            floating: false,
            pinned: true,
            flexibleSpace: FlexibleSpaceBar(
              title: const Text('可滚动导航栏'),
              background: Image.network(
                'https://picsum.photos/400/200',
                fit: BoxFit.cover,
              ),
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (context, index) {
                return ListTile(
                  title: Text('项目 $index'),
                );
              },
              childCount: 50,
            ),
          ),
        ],
      ),
    );
  }
}

案例7:自定义高度的 AppBar

dart 复制代码
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: CustomHeightAppBarPage(),
    );
  }
}

class CustomHeightAppBarPage extends StatelessWidget {
  const CustomHeightAppBarPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('自定义高度'),
        toolbarHeight: 80, // 自定义高度
        leading: Padding(
          padding: const EdgeInsets.all(8),
          child: CircleAvatar(
            backgroundImage: const NetworkImage('https://picsum.photos/100'),
          ),
        ),
      ),
      body: const Center(child: Text('自定义高度示例')),
    );
  }
}

案例8:带进度条的 AppBar

dart 复制代码
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: ProgressAppBar(),
    );
  }
}

class ProgressAppBar extends StatefulWidget {
  const ProgressAppBar({Key? key}) : super(key: key);

  @override
  State<ProgressAppBar> createState() => _ProgressAppBarState();
}

class _ProgressAppBarState extends State<ProgressAppBar> {
  bool _isLoading = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('进度条示例'),
        actions: [
          IconButton(
            icon: const Icon(Icons.refresh),
            onPressed: () {
              setState(() {
                _isLoading = true;
              });
              Future.delayed(const Duration(seconds: 2), () {
                setState(() {
                  _isLoading = false;
                });
              });
            },
          ),
        ],
        bottom: _isLoading
            ? const PreferredSize(
                preferredSize: Size.fromHeight(4),
                child: LinearProgressIndicator(),
              )
            : null,
      ),
      body: const Center(child: Text('点击刷新按钮查看进度条')),
    );
  }
}

案例9:多行标题

dart 复制代码
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MultiLineTitlePage(),
    );
  }
}

class MultiLineTitlePage extends StatelessWidget {
  const MultiLineTitlePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              '主标题',
              style: TextStyle(fontSize: 18),
            ),
            Text(
              '副标题',
              style: TextStyle(fontSize: 12),
            ),
          ],
        ),
      ),
      body: const Center(child: Text('多行标题示例')),
    );
  }
}

案例10:自定义形状

dart 复制代码
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: CustomShapeAppBarPage(),
    );
  }
}

class CustomShapeAppBarPage extends StatelessWidget {
  const CustomShapeAppBarPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('自定义形状'),
        shape: const RoundedRectangleBorder(
          borderRadius: BorderRadius.vertical(
            bottom: Radius.circular(30),
          ),
        ),
      ),
      body: const Center(child: Text('自定义形状示例')),
    );
  }
}

完整示例

dart 复制代码
import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: AppBarDemo(),
    );
  }
}

class AppBarDemo extends StatelessWidget {
  const AppBarDemo({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('AppBar 示例'),
        centerTitle: true,
        leading: IconButton(
          icon: const Icon(Icons.menu),
          onPressed: () {
            ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(content: Text('打开菜单')),
            );
          },
        ),
        actions: [
          IconButton(
            icon: const Icon(Icons.search),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(content: Text('搜索')),
              );
            },
          ),
          IconButton(
            icon: const Icon(Icons.notifications),
            onPressed: () {
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(content: Text('通知')),
              );
            },
          ),
          PopupMenuButton(
            itemBuilder: (context) => const [
              PopupMenuItem(
                value: 'settings',
                child: Text('设置'),
              ),
              PopupMenuItem(
                value: 'about',
                child: Text('关于'),
              ),
            ],
            onSelected: (value) {
              print('选择了: $value');
            },
          ),
        ],
      ),
      body: ListView(
        padding: const EdgeInsets.all(20),
        children: [
          ElevatedButton(
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => const GradientAppBarPage(),
                ),
              );
            },
            child: const Text('渐变导航栏'),
          ),
          const SizedBox(height: 10),
          ElevatedButton(
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => const TabBarPage(),
                ),
              );
            },
            child: const Text('TabBar 导航栏'),
          ),
          const SizedBox(height: 10),
          ElevatedButton(
            onPressed: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => const ScrollableAppBarPage(),
                ),
              );
            },
            child: const Text('可滚动导航栏'),
          ),
        ],
      ),
    );
  }
}

class GradientAppBarPage extends StatelessWidget {
  const GradientAppBarPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('渐变导航栏'),
        flexibleSpace: Container(
          decoration: const BoxDecoration(
            gradient: LinearGradient(
              colors: [Colors.blue, Colors.purple],
            ),
          ),
        ),
      ),
      body: const Center(child: Text('渐变导航栏示例')),
    );
  }
}

class TabBarPage extends StatelessWidget {
  const TabBarPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('TabBar'),
          bottom: const TabBar(
            tabs: [
              Tab(text: '标签1'),
              Tab(text: '标签2'),
              Tab(text: '标签3'),
            ],
          ),
        ),
        body: const TabBarView(
          children: [
            Center(child: Text('页面 1')),
            Center(child: Text('页面 2')),
            Center(child: Text('页面 3')),
          ],
        ),
      ),
    );
  }
}

class ScrollableAppBarPage extends StatelessWidget {
  const ScrollableAppBarPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: [
          const SliverAppBar(
            expandedHeight: 200,
            pinned: true,
            flexibleSpace: FlexibleSpaceBar(
              title: Text('可滚动'),
              background: ColoredBox(
                color: Colors.blue,
              ),
            ),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (context, index) {
                return ListTile(title: Text('项目 $index'));
              },
              childCount: 50,
            ),
          ),
        ],
      ),
    );
  }
}

常见问题

1. 如何去除返回按钮?

dart 复制代码
AppBar(
  automaticallyImplyLeading: false,  // 不自动显示返回按钮
  title: Text('标题'),
)

2. 如何自定义返回按钮?

dart 复制代码
AppBar(
  leading: IconButton(
    icon: Icon(Icons.arrow_back),
    onPressed: () {
      Navigator.pop(context);
    },
  ),
  title: Text('标题'),
)

3. 如何去除阴影?

dart 复制代码
AppBar(
  title: Text('标题'),
  elevation: 0,  // 无阴影
)

4. 如何让内容延伸到 AppBar 下方?

dart 复制代码
Scaffold(
  extendBodyBehindAppBar: true,
  appBar: AppBar(
    backgroundColor: Colors.transparent,
    elevation: 0,
  ),
  body: Container(),
)

属性速查表

属性 说明
title 标题
leading 左侧组件
actions 右侧操作按钮
backgroundColor 背景颜色
centerTitle 标题是否居中
elevation 阴影高度
bottom 底部组件
flexibleSpace 灵活空间
toolbarHeight 工具栏高度
shape 形状

总结

AppBar 的核心要点:

  1. 显示页面标题和操作按钮
  2. leading 设置左侧组件
  3. actions 设置右侧按钮
  4. bottom 可以放 TabBar
  5. flexibleSpace 可以自定义背景

记住:

  • AppBar 通常放在 Scaffold 的 appBar 属性中
  • centerTitle 控制标题居中
  • elevation 控制阴影
  • 可以使用 SliverAppBar 实现滚动效果

AppBar 是应用的门面,设计好它能提升用户体验!

相关推荐
小哥Mark3 小时前
Flutter开发鸿蒙年味 + 实用实战应用|绿色烟花:电子烟花 + 手持烟花
flutter·华为·harmonyos
css趣多多3 小时前
一个UI内置组件el-scrollbar
前端·javascript·vue.js
-凌凌漆-3 小时前
【vue】pinia中的值使用 v-model绑定出现[object Object]
javascript·vue.js·ecmascript
C澒3 小时前
前端整洁架构(Clean Architecture)实战解析:从理论到 Todo 项目落地
前端·架构·系统架构·前端框架
C澒3 小时前
Remesh 框架详解:基于 CQRS 的前端领域驱动设计方案
前端·架构·前端框架·状态模式
Charlie_lll4 小时前
学习Three.js–雪花
前端·three.js
onebyte8bits4 小时前
前端国际化(i18n)体系设计与工程化落地
前端·国际化·i18n·工程化
C澒4 小时前
前端分层架构实战:DDD 与 Clean Architecture 在大型业务系统中的落地路径与项目实践
前端·架构·系统架构·前端框架
BestSongC4 小时前
行人摔倒检测系统 - 前端文档(1)
前端·人工智能·目标检测
一只大侠的侠5 小时前
Flutter开源鸿蒙跨平台训练营 Day 3
flutter·开源·harmonyos