2.Flutter开发

2026-06-02 14:19 354 阅读

二.Flutter开发

1.环境搭建

先参考官方环境搭建文档 搭建完成基础环境后,还需要安装插件Awesome Flutter Snippets。

flutter 常用命令

# 创建新项目
flutter create my_app

# 创建项目(指定平台)
flutter create --platforms=android,windows my_app

# 运行项目
flutter run

# 运行并指定设备
flutter run -d chrome 

# 以发布模式运行
flutter run --release 

# 检查Flutter环境配置
flutter doctor

# 列出连接的设备
flutter devices

# 获取所有依赖包
flutter pub get

# 添加依赖包
flutter pub add package_name

# 添加特定版本的依赖
flutter pub add package_name@^1.0.0

# 添加开发依赖
flutter pub add --dev package_name

# 移除依赖包
flutter pub remove package_name

# 清理缓存(解决依赖问题)
flutter clean

# 显示帮助信息
flutter help

# 查看Flutter版本
flutter --version

# 列出所有可用的命令
flutter commands

# 构建APK(包含 arm64-v8a、armeabi-v7a、x86_64)
flutter build apk

# 构建拆分APK(按架构,会生成多个 APK 文件)
flutter build apk --split-per-abi

# 构建App Bundle
flutter build appbundle

# 构建iOS(需要Mac)
flutter build ios

# 构建Web
flutter build web

# 构建桌面应用
flutter build windows
flutter build macos
flutter build linux

项目结构

my_flutter_app/
├── android/                 # Android 原生代码目录
├── ios/                     # iOS 原生代码目录
├── lib/                      # Flutter 核心代码目录(主要开发目录)
│   ├── main.dart            # 应用程序入口文件
│   ├── models/              # 数据模型
│   ├── views/                # 视图/页面
│   ├── widgets/              # 可复用的组件
│   ├── services/             # 服务(API、数据库等)
│   ├── utils/                # 工具类/辅助函数
│   ├── providers/            # 状态管理(如使用 Provider)
│   └── routes/               # 路由配置
├── test/                     # 测试代码目录
├── web/                      # Web 平台代码
├── macos/                    # macOS 桌面平台代码
├── windows/                  # Windows 桌面平台代码
├── linux/                    # Linux 桌面平台代码
├── assets/                   # 静态资源文件
│   ├── images/               # 图片资源
│   ├── fonts/                # 字体文件
│   ├── icons/                # 图标文件
│   └── json/                 # JSON 数据文件
├── build/                    # 构建输出目录(自动生成,忽略)
├── .dart_tool/               # Dart 工具缓存(自动生成,忽略)
├── .idea/                    # IDE 配置目录(自动生成,忽略)
├── .vscode/                  # VS Code 配置
├── .metadata                 # Flutter 项目元数据
├── .packages                 # 依赖包映射(自动生成)
├── .flutter-plugins          # Flutter 插件列表(自动生成)
├── pubspec.yaml              # 项目配置文件(依赖、资源等)
├── pubspec.lock              # 依赖版本锁定文件
├── README.md                 # 项目说明文档
├── CHANGELOG.md              # 版本更新日志
├── LICENSE                   # 开源协议
└── analysis_options.yaml     # 代码分析配置

2.脚手架Scoffold

Scaffold 是 Flutter 中实现 Material Design 布局结构的基础组件,它提供了标准的应用框架。

基本结构

Scaffold(
  appBar: AppBar(),           // 顶部导航栏
  body: Container(),          // 主体内容
  floatingActionButton: FloatingActionButton(), // 悬浮按钮
  bottomNavigationBar: BottomNavigationBar(),   // 底部导航栏
  drawer: Drawer(),           // 左侧抽屉菜单
  endDrawer: Drawer(),        // 右侧抽屉菜单
  backgroundColor: Colors.white, // 背景颜色
)

基础示例

import 'package:flutter/material.dart';

void main() {
  runApp( MaterialApp(
    title: "Scaffold学习项目",
    home: Scaffold(
      appBar: AppBar(
        title: Text("Scaffold测试"),
      ),
      body: Container(
        child: Center(
          child: Text("中间内容"),
        ),
      ),
      bottomNavigationBar: Container(
        height: 80,
        child: Center(
          child: Text("底部内容"),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){},
        child: Icon(Icons.add),
      ),
      // 左侧抽屉
      drawer: Drawer(
        child: Center(
          child: Text("左侧侧边栏"),
        ),
      ),
      // 右侧抽屉
      endDrawer: Drawer(
        child: Center(
          child: Text("右侧侧边栏"),
        ),
      ),
      backgroundColor: Colors.blueGrey,
    ),
  ));
}

3.无状态组件StatelessWidget

  • 定义:创建一个新的类,继承StatelessWidget类并实现build方法
  • 要求:build返回一个widget
  • 场景:纯展示型组件,没有用户交互操作

案例

import 'package:flutter/material.dart';

void main(List<String> args) {
  runApp(MainPage());
}
class MainPage extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "StatelessWidget无状态组件",
      home: Scaffold(
        appBar: AppBar(
          title: Text("StatelessWidget无状态组件"),
        ),
        body: Container(
          child: Center(
            child: Text("中间内容."),
          ),
        ),
        bottomNavigationBar: Container(
          height: 80,
          child: Center(
            child: Text("底部内容"),
          ),
        ),
      ),
    );
  }
  
}

生命周期

class MyStatelessWidget extends StatelessWidget {
  // 1. 构造函数(创建时执行)
  MyStatelessWidget({Key? key}) : super(key: key) {
    print('1. 构造函数执行');
  }

  @override
  Widget build(BuildContext context) {
    // 2. build 方法执行(绘制UI)
    print('2. build 方法执行');
    return Container();
  }
  
  // ⚠️ StatelessWidget 只有这两个阶段!
  // 没有更新、没有销毁,一次构建后就不再变化
}

4.有状态组件StatefulWidget

案例

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

// StatefulWidget 定义
class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => _MyAppState();
}

// 状态类
class _MyAppState extends State<MyApp> {
  int count = 0;

  // 点击时调用的方法
  void addNumber() {
    setState(() {
      count++;  // 数字加1
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('有状态组件')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('你点击了 $count 次'),  // 显示变化的数字
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: addNumber,     // 点击按钮
                child: Text('点我'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

生命周期

import 'package:flutter/material.dart';

void main() {
  runApp(MainPage());
}

class MainPage extends StatefulWidget {
  MainPage({Key? key}) : super(key: key) {
    print('🔵 StatefulWidget 构造函数');
  }

  @override
  State<MainPage> createState() {
    print('🔵 createState 方法');
    return _MainPageState();
  }
}

class _MainPageState extends State<MainPage> {
  // 1. 初始化状态变量
  int _counter = 0;
  
  // 2. 初始化生命周期
  @override
  void initState() {
    super.initState();
    print('🟢 1. initState 执行 - 组件初始化');
    // 适合在这里做:网络请求、订阅、初始化数据
  }

  // 3. 依赖变化时(较少用)
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    print('🟡 2. didChangeDependencies 执行 - 依赖变化');
    // 当依赖的 InheritedWidget 变化时调用
  }

  // 4. 组件更新时
  @override
  void didUpdateWidget(MainPage oldWidget) {
    super.didUpdateWidget(oldWidget);
    print('🟠 3. didUpdateWidget 执行 - 组件更新');
    // 当父组件重建导致当前组件更新时调用
  }

  // 5. 构建UI(可能多次执行)
  @override
  Widget build(BuildContext context) {
    print('🟣 4. build 执行 - 绘制UI');
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('生命周期演示'),
          actions: [
            IconButton(
              icon: Icon(Icons.refresh),
              onPressed: () {
                // 触发重建
                setState(() {});
              },
            ),
          ],
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('点击次数: $_counter'),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: () {
                  setState(() {
                    _counter++;
                    print('🟣 setState 触发 - 界面更新');
                  });
                },
                child: Text('点我'),
              ),
              SizedBox(height: 30),
              Container(
                padding: EdgeInsets.all(16),
                color: Colors.grey[200],
                child: Column(
                  children: [
                    Text('生命周期顺序:', style: TextStyle(fontWeight: FontWeight.bold)),
                    Text('1. 构造函数 → 2. createState'),
                    Text('3. initState → 4. didChangeDependencies'),
                    Text('5. build → (等待交互)'),
                    Text('6. setState → 重新build'),
                    Text('7. dispose → 组件销毁'),
                  ],
                ),
              ),
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            // 导航到新页面演示 dispose
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => SecondPage()),
            );
          },
          child: Icon(Icons.arrow_forward),
        ),
      ),
    );
  }

  // 6. 组件销毁时
  @override
  void dispose() {
    print('🔴 5. dispose 执行 - 组件销毁');
    // 适合在这里:取消订阅、释放资源
    super.dispose();
  }
}

// 第二个页面,演示 dispose
class SecondPage extends StatefulWidget {
  @override
  _SecondPageState createState() => _SecondPageState();
}

class _SecondPageState extends State<SecondPage> {
  @override
  void initState() {
    super.initState();
    print('🟢 第二页 initState');
  }

  @override
  void dispose() {
    print('🔴 第二页 dispose');
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('第二页'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('返回'),
        ),
      ),
    );
  }
}

生命周期流程图

StatefulWidget 创建
       ↓
【构造函数】 → 创建组件
       ↓
【createState】 → 创建状态对象
       ↓
【initState】 → 初始化(只执行一次)
       ↓
【didChangeDependencies】 → 依赖变化(可能执行多次)
       ↓
【build】 → 构建UI(可能执行多次)
       ↓
    ↙️ ↘️
交互触发   父组件重建
【setState】 【didUpdateWidget】
    ↘️ ↙️
    【build】(重新构建)
       ↓
【dispose】 → 组件销毁(只执行一次)

5.手势

import 'package:flutter/material.dart';

void main() {
  runApp( MaterialApp(
    title: "Scaffold学习项目",
    home: Scaffold(
      appBar: AppBar(
        title: Text("Scaffold测试"),
      ),
      body: Container(
        child: Center(
          child: GestureDetector(
            onTap: (){
              print("点击");
            },
            onDoubleTap: (){
              print("双击");
            },
            child: Text("中间内容"),
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          print("悬浮按钮点击");
        },
        child: Icon(Icons.add),
      ),
    ),
  ));
}

6.状态更新

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

// StatefulWidget 定义
class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => _MyAppState();
}

// 状态类
class _MyAppState extends State<MyApp> {
  int count = 0;

  // 点击时调用的方法
  void addNumber() {
    setState(() {
      count++;  // 数字加1
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('有状态组件')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('你点击了 $count 次'),  // 显示变化的数字
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: addNumber,     // 点击按钮
                child: Text('点我'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

7. 基础组件

基础组件是Flutter中最常用的UI元素,用于展示内容和接收用户输入。

7.1 Text - 文本组件

组件介绍: Text是Flutter中最基础的文本显示组件,用于展示各种格式的文本内容。它支持设置字体大小、颜色、粗细、对齐方式等样式属性,还可以处理文本溢出、最多显示行数等情况。

核心属性:

  • data / child:要显示的文本内容
  • style:文本样式(TextStyle对象)
  • textAlign:对齐方式(left/right/center/justify)
  • maxLines:最大显示行数
  • overflow:文本溢出处理方式

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Text组件示例')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              // 基础文本
              Text('Hello Flutter'),
              
              SizedBox(height: 20),
              
              // 带样式的文本
              Text(
                '样式丰富的文本',
                style: TextStyle(
                  fontSize: 24,
                  color: Colors.blue,
                  fontWeight: FontWeight.bold,
                ),
              ),
              
              SizedBox(height: 20),
              
              // 带溢出处理的文本
              Text(
                '这是一段很长的文本,用来演示Text组件的溢出处理效果',
                maxLines: 1,
                overflow: TextOverflow.ellipsis,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

7.2 Button - 按钮组件

组件介绍: Flutter提供了多种按钮组件,用于响应用户的点击操作。不同类型的按钮有不同的视觉效果,适用于不同的场景。

按钮类型:

  • ElevatedButton:凸起按钮,有阴影效果,适用于主要操作
  • TextButton:文本按钮,无背景,适用于次要操作
  • OutlinedButton:边框按钮,有边框,适用于中等强调的操作
  • IconButton:图标按钮,只显示图标
  • FloatingActionButton:悬浮按钮,通常放在屏幕右下角

核心属性:

  • onPressed:点击回调函数(设为null时按钮禁用)
  • child:按钮内容(文本或图标)
  • style:按钮样式

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('按钮组件示例')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              // 凸起按钮
              ElevatedButton(
                onPressed: () => print('点击了ElevatedButton'),
                child: Text('ElevatedButton'),
              ),
              
              SizedBox(height: 20),
              
              // 文本按钮
              TextButton(
                onPressed: () => print('点击了TextButton'),
                child: Text('TextButton'),
              ),
              
              SizedBox(height: 20),
              
              // 边框按钮
              OutlinedButton(
                onPressed: () => print('点击了OutlinedButton'),
                child: Text('OutlinedButton'),
              ),
              
              SizedBox(height: 20),
              
              // 图标按钮
              IconButton(
                onPressed: () => print('点击了IconButton'),
                icon: Icon(Icons.favorite),
                color: Colors.red,
              ),
            ],
          ),
        ),
        // 悬浮按钮通常在Scaffold的floatingActionButton位置
        floatingActionButton: FloatingActionButton(
          onPressed: () => print('点击了FloatingActionButton'),
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

7.3 Image - 图片组件

组件介绍: Image组件用于在应用中显示图片,支持从不同来源加载图片:网络、本地资源、文件、内存等。它提供了丰富的参数来控制图片的显示方式。

图片来源:

  • Image.network:从网络加载图片
  • Image.asset:从项目资源加载图片
  • Image.file:从本地文件加载图片
  • Image.memory:从内存数据加载图片

核心属性:

  • fit:图片填充模式(cover/contain/fill等)
  • width/height:图片宽高
  • loadingBuilder:加载中的占位图
  • errorBuilder:加载失败时的显示内容

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('图片组件示例')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              // 网络图片
              Image.network(
                'https://picsum.photos/200/150',
                width: 200,
                height: 150,
                fit: BoxFit.cover,
              ),
              
              SizedBox(height: 20),
              
              // 带加载状态的网络图片
              Image.network(
                'https://picsum.photos/200/150?image=2',
                width: 200,
                height: 150,
                fit: BoxFit.cover,
                loadingBuilder: (context, child, progress) {
                  if (progress == null) return child;
                  return Center(
                    child: CircularProgressIndicator(
                      value: progress.cumulativeBytesLoaded / 
                             (progress.expectedTotalBytes ?? 1),
                    ),
                  );
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

7.4 Icon - 图标组件

组件介绍: Icon组件用于显示Material Design图标,Flutter内置了大量常用的图标。图标可以设置颜色、大小,也可以自定义图标。

核心属性:

  • icon:要显示的图标(Icons.xxx)
  • size:图标大小
  • color:图标颜色

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('图标组件示例')),
        body: Center(
          child: Wrap(
            spacing: 30,
            children: [
              Icon(Icons.home, size: 40, color: Colors.blue),
              Icon(Icons.favorite, size: 40, color: Colors.red),
              Icon(Icons.settings, size: 40, color: Colors.grey),
              Icon(Icons.notifications, size: 40, color: Colors.amber),
              Icon(Icons.person, size: 40, color: Colors.green),
            ],
          ),
        ),
      ),
    );
  }
}

7.5 TextField - 文本输入框

组件介绍: TextField是Flutter中的文本输入组件,用于接收用户输入的文字。它支持密码输入、多行输入、输入格式验证等功能。

核心属性:

  • controller:控制文本的控制器
  • decoration:输入框装饰(边框、标签、提示文字等)
  • obscureText:是否隐藏输入(用于密码)
  • keyboardType:键盘类型(数字、邮箱、电话等)
  • onChanged:内容变化时的回调
  • onSubmitted:提交时的回调

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final TextEditingController _controller = TextEditingController();
  String _displayText = '';

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('TextField示例')),
        body: Padding(
          padding: EdgeInsets.all(20),
          child: Column(
            children: [
              // 基础输入框
              TextField(
                decoration: InputDecoration(
                  labelText: '用户名',
                  hintText: '请输入用户名',
                  border: OutlineInputBorder(),
                  prefixIcon: Icon(Icons.person),
                ),
              ),
              
              SizedBox(height: 20),
              
              // 密码输入框
              TextField(
                obscureText: true,
                decoration: InputDecoration(
                  labelText: '密码',
                  hintText: '请输入密码',
                  border: OutlineInputBorder(),
                  prefixIcon: Icon(Icons.lock),
                ),
              ),
              
              SizedBox(height: 20),
              
              // 带回调的输入框
              TextField(
                controller: _controller,
                decoration: InputDecoration(
                  labelText: '输入内容',
                  border: OutlineInputBorder(),
                ),
                onChanged: (value) {
                  setState(() {
                    _displayText = value;
                  });
                },
              ),
              
              SizedBox(height: 20),
              
              Text('你输入的是:$_displayText'),
            ],
          ),
        ),
      ),
    );
  }
}

8. 布局组件

布局组件用于组织和排列其他组件,决定它们在屏幕上的位置和大小。


8.1 Container - 容器组件

组件介绍: Container是Flutter中最常用的布局组件,相当于一个"盒子",可以容纳一个子组件,并对其进行装饰、定位、大小调整等操作。

核心属性:

  • width/height:容器宽高
  • padding/margin:内边距/外边距
  • decoration:装饰(背景颜色、边框、圆角、阴影等)
  • alignment:子组件对齐方式
  • color:背景颜色(简单场景使用)

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Container示例')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              // 简单容器
              Container(
                width: 200,
                height: 100,
                color: Colors.blue,
                child: Center(
                  child: Text('简单容器', style: TextStyle(color: Colors.white)),
                ),
              ),
              
              SizedBox(height: 20),
              
              // 带边框和圆角的容器
              Container(
                width: 200,
                height: 100,
                padding: EdgeInsets.all(10),
                decoration: BoxDecoration(
                  color: Colors.white,
                  border: Border.all(color: Colors.red, width: 2),
                  borderRadius: BorderRadius.circular(10),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.grey,
                      blurRadius: 5,
                      offset: Offset(2, 2),
                    ),
                  ],
                ),
                child: Center(child: Text('带边框和圆角')),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

8.2 Row - 水平布局组件

组件介绍: Row是一个水平排列子组件的布局组件,子组件会从左到右依次排列。它类似于HTML中的flex布局。

核心属性:

  • mainAxisAlignment:主轴(水平方向)的对齐方式
  • crossAxisAlignment:交叉轴(垂直方向)的对齐方式
  • children:子组件列表

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Row示例')),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text('默认左对齐:'),
              Container(
                color: Colors.grey[200],
                child: Row(
                  children: [
                    Container(width: 50, height: 50, color: Colors.red),
                    Container(width: 50, height: 50, color: Colors.green),
                    Container(width: 50, height: 50, color: Colors.blue),
                  ],
                ),
              ),
              
              SizedBox(height: 20),
              
              Text('居中对齐:'),
              Container(
                color: Colors.grey[200],
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Container(width: 50, height: 50, color: Colors.red),
                    Container(width: 50, height: 50, color: Colors.green),
                    Container(width: 50, height: 50, color: Colors.blue),
                  ],
                ),
              ),
              
              SizedBox(height: 20),
              
              Text('两端对齐:'),
              Container(
                color: Colors.grey[200],
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Container(width: 50, height: 50, color: Colors.red),
                    Container(width: 50, height: 50, color: Colors.green),
                    Container(width: 50, height: 50, color: Colors.blue),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

8.3 Column - 垂直布局组件

组件介绍: Column是一个垂直排列子组件的布局组件,子组件会从上到下依次排列。它是Row的垂直版本。

核心属性:

  • mainAxisAlignment:主轴(垂直方向)的对齐方式
  • crossAxisAlignment:交叉轴(水平方向)的对齐方式
  • children:子组件列表

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Column示例')),
        body: Center(
          child: Container(
            height: 300,
            color: Colors.grey[200],
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Container(width: 100, height: 50, color: Colors.red),
                Container(width: 100, height: 50, color: Colors.green),
                Container(width: 100, height: 50, color: Colors.blue),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

8.4 Expanded - 弹性布局组件

组件介绍: Expanded用于在Row、Column或Flex中展开子组件,让它填充剩余空间。可以设置flex参数来控制多个Expanded之间的比例。

核心属性:

  • flex:弹性因子,决定占据剩余空间的比例
  • child:要展开的子组件

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Expanded示例')),
        body: Center(
          child: Column(
            children: [
              Text('1:2:1 比例布局:'),
              Container(
                height: 100,
                color: Colors.grey[200],
                child: Row(
                  children: [
                    Expanded(
                      flex: 1,
                      child: Container(color: Colors.red, child: Center(child: Text('1'))),
                    ),
                    Expanded(
                      flex: 2,
                      child: Container(color: Colors.green, child: Center(child: Text('2'))),
                    ),
                    Expanded(
                      flex: 1,
                      child: Container(color: Colors.blue, child: Center(child: Text('1'))),
                    ),
                  ],
                ),
              ),
              
              SizedBox(height: 20),
              
              Text('搜索框 + 按钮布局:'),
              Container(
                padding: EdgeInsets.all(10),
                color: Colors.grey[200],
                child: Row(
                  children: [
                    Expanded(
                      child: TextField(
                        decoration: InputDecoration(
                          hintText: '搜索...',
                          border: OutlineInputBorder(),
                        ),
                      ),
                    ),
                    SizedBox(width: 10),
                    ElevatedButton(
                      onPressed: () {},
                      child: Text('搜索'),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

8.5 Stack - 层叠布局组件

组件介绍: Stack允许子组件叠加在一起,后添加的子组件会覆盖在先添加的子组件上面。结合Positioned可以精确控制子组件的位置。

核心属性:

  • alignment:未使用Positioned的子组件的对齐方式
  • children:要叠加的子组件列表

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Stack示例')),
        body: Center(
          child: Container(
            width: 300,
            height: 300,
            color: Colors.grey[200],
            child: Stack(
              children: [
                // 底层的红色方块
                Container(
                  width: 200,
                  height: 200,
                  color: Colors.red,
                ),
                
                // 中间的绿色方块(偏移位置)
                Positioned(
                  top: 50,
                  left: 50,
                  child: Container(
                    width: 200,
                    height: 200,
                    color: Colors.green.withOpacity(0.7),
                  ),
                ),
                
                // 顶层的蓝色文字
                Positioned(
                  bottom: 50,
                  right: 50,
                  child: Container(
                    padding: EdgeInsets.all(10),
                    color: Colors.blue,
                    child: Text(
                      '顶层文字',
                      style: TextStyle(color: Colors.white),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

8.6 Center - 居中布局组件

组件介绍: Center是一个简单的布局组件,它会将子组件放在父容器的中心位置。相当于alignment: Alignment.center的Container。

核心属性:

  • child:要居中的子组件

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Center示例')),
        body: Center(
          child: Container(
            width: 200,
            height: 200,
            color: Colors.blue,
            child: Center(
              child: Text(
                '居中内容',
                style: TextStyle(color: Colors.white, fontSize: 20),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

8.7 Padding - 内边距组件

组件介绍: Padding用于给子组件添加内边距,即子组件与父容器边界之间的空白区域。

核心属性:

  • padding:内边距大小(EdgeInsets对象)
  • child:子组件

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Padding示例')),
        body: Column(
          children: [
            // 没有内边距
            Container(
              color: Colors.grey[200],
              child: Container(
                color: Colors.blue,
                child: Text('没有内边距'),
              ),
            ),
            
            SizedBox(height: 20),
            
            // 有内边距
            Container(
              color: Colors.grey[200],
              child: Padding(
                padding: EdgeInsets.all(20),
                child: Container(
                  color: Colors.blue,
                  child: Text('有20的内边距'),
                ),
              ),
            ),
            
            SizedBox(height: 20),
            
            // 不同方向的内边距
            Container(
              color: Colors.grey[200],
              child: Padding(
                padding: EdgeInsets.only(left: 30, top: 10, right: 10, bottom: 30),
                child: Container(
                  color: Colors.green,
                  child: Text('左边距30,上边距10,右边距10,下边距30'),
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

8.8 Wrap - 流式布局组件

组件介绍: Wrap类似于Row和Column,但当空间不足时会自动换行/换列。非常适合用于标签列表、按钮组等需要自动换行的场景。

核心属性:

  • direction:主轴方向(水平或垂直)
  • spacing:主轴方向间距
  • runSpacing:交叉轴方向间距
  • alignment:主轴对齐方式

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  final List<String> tags = ['Flutter', 'Dart', 'Android', 'iOS', 'Web', '前端', '后端'];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Wrap示例')),
        body: Padding(
          padding: EdgeInsets.all(20),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text('标签列表(自动换行):'),
              SizedBox(height: 10),
              
              Container(
                padding: EdgeInsets.all(10),
                color: Colors.grey[200],
                child: Wrap(
                  spacing: 10,
                  runSpacing: 10,
                  children: tags.map((tag) {
                    return Container(
                      padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                      decoration: BoxDecoration(
                        color: Colors.blue,
                        borderRadius: BorderRadius.circular(20),
                      ),
                      child: Text(
                        tag,
                        style: TextStyle(color: Colors.white),
                      ),
                    );
                  }).toList(),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

9. 滚动组件

滚动组件用于处理内容超出屏幕范围的情况,让用户可以滑动查看所有内容。


9.1 SingleChildScrollView - 单子滚动组件

组件介绍: 当单个子组件的内容可能超出屏幕范围时,用SingleChildScrollView包裹即可实现滚动。常用于表单、长文章等场景。

核心属性:

  • scrollDirection:滚动方向(默认垂直)
  • physics:滚动物理效果(弹性/阻尼等)
  • padding:内边距

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('SingleChildScrollView示例')),
        body: SingleChildScrollView(
          padding: EdgeInsets.all(20),
          child: Column(
            children: List.generate(20, (index) {
              return Container(
                margin: EdgeInsets.only(bottom: 10),
                height: 100,
                color: Colors.primaries[index % Colors.primaries.length],
                child: Center(
                  child: Text(
                    'Item ${index + 1}',
                    style: TextStyle(color: Colors.white, fontSize: 20),
                  ),
                ),
              );
            }),
          ),
        ),
      ),
    );
  }
}

9.2 ListView - 列表组件

组件介绍: ListView是最常用的滚动列表组件,用于展示大量数据的列表。它支持垂直和水平滚动,有懒加载特性,性能较好。

常用构造方法:

  • ListView:直接创建,适合少量数据
  • ListView.builder:动态构建,适合大量数据(懒加载)
  • ListView.separated:带分割线的动态列表

核心属性:

  • itemCount:列表项数量
  • itemBuilder:构建列表项的函数
  • separatorBuilder:构建分割线的函数

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('ListView示例')),
        body: ListView.builder(
          itemCount: 50,
          itemBuilder: (context, index) {
            return ListTile(
              leading: CircleAvatar(
                backgroundColor: Colors.primaries[index % Colors.primaries.length],
                child: Text('${index + 1}'),
              ),
              title: Text('标题 ${index + 1}'),
              subtitle: Text('这是第 ${index + 1} 项的描述文字'),
              trailing: Icon(Icons.arrow_forward_ios),
              onTap: () {
                print('点击了第 ${index + 1} 项');
              },
            );
          },
        ),
      ),
    );
  }
}

9.3 GridView - 网格组件

组件介绍: GridView用于展示网格布局的数据,类似于九宫格。常用于图片墙、商品展示等场景。

常用构造方法:

  • GridView.count:指定每行列数的网格
  • GridView.builder:动态构建网格(懒加载)

核心属性:

  • crossAxisCount:每行的列数
  • childAspectRatio:子元素宽高比
  • crossAxisSpacing:列间距
  • mainAxisSpacing:行间距

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('GridView示例')),
        body: GridView.count(
          crossAxisCount: 2,  // 每行2列
          childAspectRatio: 1.2,  // 宽高比
          crossAxisSpacing: 10,   // 列间距
          mainAxisSpacing: 10,    // 行间距
          padding: EdgeInsets.all(10),
          children: List.generate(20, (index) {
            return Container(
              color: Colors.primaries[index % Colors.primaries.length],
              child: Center(
                child: Text(
                  'Item ${index + 1}',
                  style: TextStyle(color: Colors.white, fontSize: 18),
                ),
              ),
            );
          }),
        ),
      ),
    );
  }
}

9.4 PageView - 页面滑动组件

组件介绍: PageView用于实现左右滑动的页面切换效果,常用于引导页、轮播图、标签页等场景。

核心属性:

  • children:页面列表
  • onPageChanged:页面切换回调
  • controller:页面控制器

简单示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('PageView示例')),
        body: PageView(
          children: [
            Container(color: Colors.red, child: Center(child: Text('第1页', style: TextStyle(color: Colors.white, fontSize: 30)))),
            Container(color: Colors.green, child: Center(child: Text('第2页', style: TextStyle(color: Colors.white, fontSize: 30)))),
            Container(color: Colors.blue, child: Center(child: Text('第3页', style: TextStyle(color: Colors.white, fontSize: 30)))),
          ],
        ),
      ),
    );
  }
}

10.页面框架组件

页面框架组件用于构建应用的整体页面结构,提供标准的布局骨架。

10.1 Scaffold - 页面脚手架

组件介绍: Scaffold 是 Material Design 页面的核心骨架,它实现了标准的应用布局结构。几乎每个页面都需要用它来组织 AppBar、底部导航、悬浮按钮等元素。

核心属性:

  • appBar:顶部导航栏
  • body:页面主体内容
  • bottomNavigationBar:底部导航栏
  • floatingActionButton:悬浮按钮
  • drawer:左侧抽屉菜单
  • endDrawer:右侧抽屉菜单
  • backgroundColor:背景颜色

简单示例:

Scaffold(
  appBar: AppBar(title: Text('首页')),
  body: Center(child: Text('页面内容')),
  bottomNavigationBar: BottomNavigationBar(
    items: [
      BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
      BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'),
    ],
  ),
  floatingActionButton: FloatingActionButton(
    onPressed: () {},
    child: Icon(Icons.add),
  ),
  drawer: Drawer(child: Center(child: Text('侧边菜单'))),
)

10.2 AppBar - 顶部导航栏

组件介绍: AppBar 位于页面顶部,通常包含标题、返回按钮、操作按钮等。它可以固定在顶部,也可以随着滚动隐藏。

核心属性:

  • title:标题
  • leading:左侧图标(默认是返回按钮)
  • actions:右侧操作按钮列表
  • backgroundColor:背景颜色
  • elevation:阴影高度
  • bottom:底部区域(常用 TabBar)

简单示例:

AppBar(
  title: Text('聊天详情'),
  leading: IconButton(
    icon: Icon(Icons.arrow_back),
    onPressed: () => Navigator.pop(context),
  ),
  actions: [
    IconButton(icon: Icon(Icons.search), onPressed: () {}),
    IconButton(icon: Icon(Icons.more_vert), onPressed: () {}),
  ],
  backgroundColor: Colors.blue,
  elevation: 4,
)

带 TabBar 的 AppBar:

AppBar(
  title: Text('分类'),
  bottom: TabBar(
    tabs: [
      Tab(text: '热门'),
      Tab(text: '推荐'),
      Tab(text: '最新'),
    ],
  ),
)

10.3 BottomNavigationBar - 底部导航栏

组件介绍: BottomNavigationBar 位于页面底部,用于在应用的主要页面之间切换。通常配合 IndexedStack 或 PageView 实现页面切换。

核心属性:

  • items:导航项列表
  • currentIndex:当前选中项索引
  • onTap:点击回调
  • type:导航类型(fixed/shifting)
  • selectedItemColor:选中项颜色

简单示例:

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  int _currentIndex = 0;
  final pages = [
    Center(child: Text('首页')),
    Center(child: Text('发现')),
    Center(child: Text('消息')),
    Center(child: Text('我的')),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: pages[_currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currentIndex,
        onTap: (index) {
          setState(() {
            _currentIndex = index;
          });
        },
        type: BottomNavigationBarType.fixed, // 超过3个用fixed
        selectedItemColor: Colors.blue,
        unselectedItemColor: Colors.grey,
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: '首页'),
          BottomNavigationBarItem(icon: Icon(Icons.explore), label: '发现'),
          BottomNavigationBarItem(icon: Icon(Icons.message), label: '消息'),
          BottomNavigationBarItem(icon: Icon(Icons.person), label: '我的'),
        ],
      ),
    );
  }
}

10.4 Drawer - 侧边抽屉菜单

组件介绍: Drawer 是从屏幕边缘滑出的侧边菜单,通常放置用户信息、导航选项、设置等。左侧常用,右侧也有(endDrawer)。

核心属性:

  • child:菜单内容
  • width:抽屉宽度(默认 304)
  • elevation:阴影高度

简单示例:

Scaffold(
  appBar: AppBar(title: Text('首页')),
  drawer: Drawer(
    child: ListView(
      padding: EdgeInsets.zero,
      children: [
        // 头部
        DrawerHeader(
          decoration: BoxDecoration(color: Colors.blue),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              CircleAvatar(
                radius: 30,
                backgroundImage: NetworkImage('头像URL'),
              ),
              SizedBox(height: 10),
              Text('用户名', style: TextStyle(color: Colors.white)),
              Text('user@example.com', style: TextStyle(color: Colors.white70)),
            ],
          ),
        ),
        // 菜单项
        ListTile(
          leading: Icon(Icons.home),
          title: Text('首页'),
          onTap: () => Navigator.pop(context),
        ),
        ListTile(
          leading: Icon(Icons.settings),
          title: Text('设置'),
          onTap: () => Navigator.pop(context),
        ),
        Divider(),
        ListTile(
          leading: Icon(Icons.logout),
          title: Text('退出登录'),
          onTap: () {},
        ),
      ],
    ),
  ),
)

10.5 FloatingActionButton - 悬浮按钮

组件介绍: FloatingActionButton 是悬浮在页面上的圆形按钮,通常用于主要操作(如添加、编辑)。可以放在 Scaffold 的 floatingActionButton 位置,也可以自定义位置。

核心属性:

  • onPressed:点击回调
  • child:图标或文字
  • backgroundColor:背景颜色
  • mini:是否迷你尺寸
  • shape:形状(默认圆形)

简单示例:

Scaffold(
  appBar: AppBar(title: Text('笔记')),
  body: ListView(...),
  floatingActionButton: FloatingActionButton(
    onPressed: () {
      // 跳转到添加笔记页面
    },
    child: Icon(Icons.add),
    backgroundColor: Colors.red,
  ),
)

扩展按钮(带文字):

FloatingActionButton.extended(
  onPressed: () {},
  icon: Icon(Icons.add),
  label: Text('添加笔记'),
  backgroundColor: Colors.green,
)

多个悬浮按钮:

Scaffold(
  floatingActionButton: Column(
    mainAxisAlignment: MainAxisAlignment.end,
    children: [
      FloatingActionButton(
        heroTag: 'btn1',
        onPressed: () {},
        child: Icon(Icons.camera),
        mini: true,
      ),
      SizedBox(height: 10),
      FloatingActionButton(
        heroTag: 'btn2',
        onPressed: () {},
        child: Icon(Icons.photo),
        mini: true,
      ),
      SizedBox(height: 10),
      FloatingActionButton(
        heroTag: 'btn3',
        onPressed: () {},
        child: Icon(Icons.add),
      ),
    ],
  ),
)

10.6 TabBar + TabBarView - 标签页

组件介绍: TabBar 和 TabBarView 配合使用,实现顶部标签页切换效果。TabBar 显示标签,TabBarView 显示对应的页面内容。

核心属性:

  • TabBar:标签栏(需要配合 TabController)
  • TabBarView:标签页内容
  • DefaultTabController:简化使用的控制器

简单示例:

class TabDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 3,
      child: Scaffold(
        appBar: AppBar(
          title: Text('标签页示例'),
          bottom: TabBar(
            tabs: [
              Tab(icon: Icon(Icons.directions_car)),
              Tab(icon: Icon(Icons.directions_transit)),
              Tab(icon: Icon(Icons.directions_bike)),
            ],
          ),
        ),
        body: TabBarView(
          children: [
            Center(child: Text('汽车内容')),
            Center(child: Text('公交内容')),
            Center(child: Text('自行车内容')),
          ],
        ),
      ),
    );
  }
}

带文字的 TabBar:

TabBar(
  tabs: [
    Tab(text: '热门'),
    Tab(text: '推荐'),
    Tab(text: '最新'),
  ],
  indicatorColor: Colors.red,  // 指示器颜色
  labelColor: Colors.blue,     // 选中标签颜色
  unselectedLabelColor: Colors.grey, // 未选中标签颜色
)

10.7 BottomSheet - 底部弹出面板

组件介绍: BottomSheet 是从屏幕底部弹出的面板,用于显示更多操作或内容。分为持久性(Persistent)和模态(Modal)两种。

核心属性:

  • builder:构建面板内容
  • backgroundColor:背景颜色
  • shape:形状(可设置圆角)

简单示例:

// 显示模态底部面板
ElevatedButton(
  onPressed: () {
    showModalBottomSheet(
      context: context,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
      ),
      builder: (context) => Container(
        height: 200,
        padding: EdgeInsets.all(20),
        child: Column(
          children: [
            Text('选择操作', style: TextStyle(fontSize: 18)),
            ListTile(
              leading: Icon(Icons.photo),
              title: Text('相册'),
              onTap: () => Navigator.pop(context),
            ),
            ListTile(
              leading: Icon(Icons.camera),
              title: Text('相机'),
              onTap: () => Navigator.pop(context),
            ),
          ],
        ),
      ),
    );
  },
  child: Text('显示底部面板'),
)

10.8 SnackBar - 底部提示条

组件介绍: SnackBar 是在屏幕底部短暂显示的轻量级提示信息,可以包含操作按钮。

核心属性:

  • content:显示内容
  • action:操作按钮
  • duration:显示时长
  • behavior:显示行为(浮动/固定)

简单示例:

ElevatedButton(
  onPressed: () {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text('操作成功'),
        action: SnackBarAction(
          label: '撤销',
          onPressed: () {
            // 撤销操作
          },
        ),
        duration: Duration(seconds: 2),
        behavior: SnackBarBehavior.floating, // 浮动显示
      ),
    );
  },
  child: Text('显示提示'),
)