Flutter 完整开发指南

Flutter 基础

1.1 开发环境搭建

1.1.1 必要工具安装

  1. Flutter SDK

    bash 复制代码
    # Windows
    # 1. 下载 Flutter SDK
    # 2. 解压到合适的目录,如 C:\flutter
    # 3. 添加 flutter\bin 到环境变量 Path
    
    # macOS
    brew install flutter
    
    # Linux
    sudo snap install flutter --classic
  2. 开发工具

    • Android Studio
    • VS Code
    • Xcode (仅 macOS)
    • Appuploader (iOS 开发助手,用于简化 iOS 应用的打包和上传流程)
  3. 环境检查

    bash 复制代码
    flutter doctor

1.1.2 IDE 配置

  1. VS Code 插件

    • Flutter
    • Dart
    • Flutter Widget Snippets
  2. Android Studio 插件

    • Flutter
    • Dart

1.1.3 创建项目

  1. 使用命令行创建

    bash 复制代码
    # 创建新项目
    flutter create my_app
    
    # 指定组织名称
    flutter create --org com.example my_app
    
    # 指定使用特定平台
    flutter create --platforms android,ios my_app
    
    # 创建包含示例代码的项目
    flutter create --sample=material.AppBar.1 my_app
  2. 使用 VS Code 创建

    • 打开 VS Code
    • 按下 Ctrl+Shift+P(Windows/Linux)或 Cmd+Shift+P(macOS)
    • 输入 Flutter: New Project
    • 选择项目存储位置
    • 输入项目名称(使用小写字母和下划线)
    • 等待项目创建和依赖安装完成
  3. 项目结构说明

    复制代码
    my_app/
    ├── android/          # Android 平台相关代码
    ├── ios/             # iOS 平台相关代码
    ├── lib/             # Dart 源代码
    │   └── main.dart    # 应用入口文件
    ├── test/            # 测试文件
    ├── web/             # Web 平台相关代码
    ├── pubspec.yaml     # 项目配置文件
    └── README.md        # 项目说明文档
  4. 运行项目

    bash 复制代码
    # 命令行运行
    cd my_app
    flutter run
    
    # VS Code 运行
    # 1. 打开项目文件夹
    # 2. 选择目标设备(模拟器或真机)
    # 3. 按 F5 或点击 "运行 > 启动调试"
  5. 常用 VS Code 快捷操作

    • Ctrl + F5(Windows/Linux)或 Cmd + F5(macOS):无调试运行
    • Ctrl + Shift + F5:重新运行
    • Shift + Alt + F:格式化代码
    • Ctrl + .:快速修复/重构
    • Ctrl + Space:触发建议
    • Ctrl + Shift + R:重新加载
  6. VS Code 常用插件推荐

    • Flutter
    • Dart
    • Flutter Widget Snippets
    • Awesome Flutter Snippets
    • Flutter Tree
    • pubspec Assist
    • Error Lens

1.2 Dart 语言基础

1.2.1 变量与数据类型

dart 复制代码
// 变量声明
var name = 'Bob';          // 类型推断
String name = 'Bob';       // 显式声明
dynamic name = 'Bob';      // 动态类型
final name = 'Bob';        // 运行时常量
const pi = 3.14;          // 编译时常量

// 内置数据类型
int age = 30;             // 整数
double height = 1.75;     // 浮点数
String name = 'Bob';      // 字符串
bool isStudent = true;    // 布尔值

1.2.2 集合类型

dart 复制代码
// List(列表)
List<String> fruits = ['apple', 'banana', 'orange'];
var numbers = <int>[1, 2, 3, 4, 5];

// Set(集合)
Set<String> uniqueNames = {'John', 'Jane', 'Bob'};

// Map(字典)
Map<String, int> scores = {
  'math': 95,
  'english': 85,
  'history': 90,
};

1.2.3 函数

dart 复制代码
// 基本函数
int add(int a, int b) {
  return a + b;
}

// 箭头函数
int multiply(int a, int b) => a * b;

// 可选参数
String greet(String name, [String? title]) {
  return title != null ? '$title $name' : 'Hello $name';
}

// 命名参数
void printPerson({
  required String name,
  int? age,
  String? address,
}) {
  print('Name: $name, Age: ${age ?? "Unknown"}, Address: ${address ?? "N/A"}');
}

// 函数作为参数
void processNumbers(List<int> numbers, int Function(int) processor) {
  for (var number in numbers) {
    print(processor(number));
  }
}

1.2.4 类与对象

dart 复制代码
class Person {
  // 属性
  final String name;
  int age;
  
  // 构造函数
  Person(this.name, this.age);
  
  // 命名构造函数
  Person.guest() : name = 'Guest', age = 0;
  
  // 方法
  void introduce() {
    print('My name is $name and I am $age years old.');
  }
  
  // Getter
  String get info => '$name ($age)';
  
  // Setter
  set setAge(int value) {
    if (value >= 0) {
      age = value;
    }
  }
}

// 继承
class Student extends Person {
  String school;
  
  Student(String name, int age, this.school) : super(name, age);
  
  @override
  void introduce() {
    super.introduce();
    print('I study at $school.');
  }
}

// Mixin
mixin Musical {
  void playMusic() {
    print('Playing music...');
  }
}

class MusicStudent extends Student with Musical {
  MusicStudent(String name, int age, String school) 
      : super(name, age, school);
}

1.3 Flutter 核心概念

1.3.1 Widget

Flutter 中一切都是 Widget,它们是用户界面的基本构建块。

  1. StatelessWidget

    dart 复制代码
    class GreetingWidget extends StatelessWidget {
      final String name;
      
      const GreetingWidget({
        Key? key,
        required this.name,
      }) : super(key: key);
      
      @override
      Widget build(BuildContext context) {
        return Text('Hello, $name!');
      }
    }
  2. StatefulWidget

    dart 复制代码
    class CounterWidget extends StatefulWidget {
      @override
      _CounterWidgetState createState() => _CounterWidgetState();
    }
    
    class _CounterWidgetState extends State<CounterWidget> {
      int _counter = 0;
      
      void _increment() {
        setState(() {
          _counter++;
        });
      }
      
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            Text('Count: $_counter'),
            ElevatedButton(
              onPressed: _increment,
              child: Text('Increment'),
            ),
          ],
        );
      }
    }

1.3.2 生命周期

dart 复制代码
class LifecycleWidget extends StatefulWidget {
  @override
  _LifecycleWidgetState createState() => _LifecycleWidgetState();
}

class _LifecycleWidgetState extends State<LifecycleWidget> {
  @override
  void initState() {
    super.initState();
    print('1. initState - 组件初始化');
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    print('2. didChangeDependencies - 依赖变化');
  }

  @override
  void didUpdateWidget(LifecycleWidget oldWidget) {
    super.didUpdateWidget(oldWidget);
    print('3. didUpdateWidget - 组件更新');
  }

  @override
  void setState(VoidCallback fn) {
    super.setState(fn);
    print('4. setState - 状态更新');
  }

  @override
  void deactivate() {
    print('5. deactivate - 组件停用');
    super.deactivate();
  }

  @override
  void dispose() {
    print('6. dispose - 组件销毁');
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    print('7. build - 构建UI');
    return Container();
  }
}

1.4 常用组件

1.4.1 基础组件

dart 复制代码
// 文本组件
Text(
  'Hello World',
  style: TextStyle(
    fontSize: 24,
    fontWeight: FontWeight.bold,
    color: Colors.blue,
  ),
)

// 图片组件
Image.network('https://example.com/image.jpg')
Image.asset('assets/images/logo.png')

// 按钮组件
ElevatedButton(
  onPressed: () {},
  child: Text('点击我'),
)

TextButton(
  onPressed: () {},
  child: Text('文本按钮'),
)

IconButton(
  icon: Icon(Icons.add),
  onPressed: () {},
)

// 输入框组件
TextField(
  decoration: InputDecoration(
    labelText: '用户名',
    hintText: '请输入用户名',
    border: OutlineInputBorder(),
  ),
  onChanged: (value) {
    print('输入内容: $value');
  },
)

1.4.2 布局组件

dart 复制代码
// Container - 容器组件
Container(
  width: 200,
  height: 200,
  padding: EdgeInsets.all(16),
  margin: EdgeInsets.symmetric(vertical: 8),
  decoration: BoxDecoration(
    color: Colors.blue,
    borderRadius: BorderRadius.circular(8),
    boxShadow: [
      BoxShadow(
        color: Colors.black26,
        offset: Offset(0, 2),
        blurRadius: 6,
      ),
    ],
  ),
  child: Text('容器内容'),
)

// Row - 水平布局
Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: [
    Text('左侧'),
    Text('中间'),
    Text('右侧'),
  ],
)

// Column - 垂直布局
Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    Text('顶部'),
    Text('中部'),
    Text('底部'),
  ],
)

// Stack - 层叠布局
Stack(
  children: [
    Image.asset('background.jpg'),
    Positioned(
      bottom: 16,
      right: 16,
      child: Text('覆盖文本'),
    ),
  ],
)

// Expanded & Flexible - 弹性布局
Row(
  children: [
    Expanded(
      flex: 2,
      child: Container(color: Colors.red),
    ),
    Flexible(
      flex: 1,
      child: Container(color: Colors.blue),
    ),
  ],
)

1.5 布局与导航

1.5.1 基本页面布局

dart 复制代码
Scaffold(
  appBar: AppBar(
    title: Text('应用标题'),
    actions: [
      IconButton(
        icon: Icon(Icons.settings),
        onPressed: () {},
      ),
    ],
  ),
  body: Center(
    child: Text('页面内容'),
  ),
  floatingActionButton: FloatingActionButton(
    onPressed: () {},
    child: Icon(Icons.add),
  ),
  drawer: Drawer(
    child: ListView(
      children: [
        DrawerHeader(
          child: Text('侧边栏头部'),
          decoration: BoxDecoration(
            color: Colors.blue,
          ),
        ),
        ListTile(
          title: Text('菜单项 1'),
          onTap: () {},
        ),
      ],
    ),
  ),
)

1.5.2 导航

dart 复制代码
// 基本导航
Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => SecondScreen(),
  ),
);

// 带参数导航
Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => DetailScreen(id: 123),
  ),
);

// 命名路由配置
MaterialApp(
  initialRoute: '/',
  routes: {
    '/': (context) => HomeScreen(),
    '/detail': (context) => DetailScreen(),
    '/settings': (context) => SettingsScreen(),
  },
)

// 使用命名路由
Navigator.pushNamed(
  context,
  '/detail',
  arguments: {'id': 123},
);

// 获取路由参数
class DetailScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final args = ModalRoute.of(context)!.settings.arguments as Map;
    return Scaffold(
      body: Center(
        child: Text('详情页 ID: ${args['id']}'),
      ),
    );
  }
}

Flutter 进阶

2.1 状态管理

2.1.1 Provider

dart 复制代码
// 1. 定义数据模型
class Counter with ChangeNotifier {
  int _count = 0;
  int get count => _count;

  void increment() {
    _count++;
    notifyListeners();
  }
}

// 2. 提供状态
void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => Counter(),
      child: MyApp(),
    ),
  );
}

// 3. 使用状态
class CounterWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        // 读取状态
        Consumer<Counter>(
          builder: (context, counter, child) {
            return Text('Count: ${counter.count}');
          },
        ),
        // 修改状态
        ElevatedButton(
          onPressed: () {
            context.read<Counter>().increment();
          },
          child: Text('增加'),
        ),
      ],
    );
  }
}

2.1.2 GetX

dart 复制代码
// 1. 定义控制器
class CounterController extends GetxController {
  var count = 0.obs;

  void increment() => count++;
}

// 2. 使用控制器
class CounterPage extends StatelessWidget {
  final controller = Get.put(CounterController());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: [
            // 自动更新UI
            Obx(() => Text('Count: ${controller.count}')),
            ElevatedButton(
              onPressed: controller.increment,
              child: Text('增加'),
            ),
          ],
        ),
      ),
    );
  }
}

2.2 网络请求

2.2.1 Dio 网络请求

dart 复制代码
class ApiService {
  final Dio _dio = Dio();
  
  ApiService() {
    _dio.options.baseUrl = 'https://api.example.com';
    _dio.options.connectTimeout = 5000;
    _dio.options.receiveTimeout = 3000;
    
    // 添加拦截器
    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) {
        // 请求前处理
        options.headers['Authorization'] = 'Bearer token';
        return handler.next(options);
      },
      onResponse: (response, handler) {
        // 响应处理
        return handler.next(response);
      },
      onError: (DioError e, handler) {
        // 错误处理
        return handler.next(e);
      },
    ));
  }

  // GET 请求
  Future<List<Post>> getPosts() async {
    try {
      final response = await _dio.get('/posts');
      return (response.data as List)
          .map((json) => Post.fromJson(json))
          .toList();
    } catch (e) {
      throw Exception('Failed to load posts');
    }
  }

  // POST 请求
  Future<Post> createPost(Post post) async {
    try {
      final response = await _dio.post(
        '/posts',
        data: post.toJson(),
      );
      return Post.fromJson(response.data);
    } catch (e) {
      throw Exception('Failed to create post');
    }
  }
}

2.2.2 GraphQL 请求

dart 复制代码
// 1. 定义查询
const String getPostsQuery = r'''
  query GetPosts {
    posts {
      id
      title
      content
      author {
        name
      }
    }
  }
''';

// 2. 实现 GraphQL 客户端
class GraphQLService {
  late GraphQLClient _client;

  GraphQLService() {
    final HttpLink httpLink = HttpLink('https://api.example.com/graphql');
    
    _client = GraphQLClient(
      link: httpLink,
      cache: GraphQLCache(),
    );
  }

  Future<List<Post>> getPosts() async {
    try {
      final QueryResult result = await _client.query(
        QueryOptions(
          document: gql(getPostsQuery),
        ),
      );

      if (result.hasException) {
        throw result.exception!;
      }

      return (result.data!['posts'] as List)
          .map((json) => Post.fromJson(json))
          .toList();
    } catch (e) {
      throw Exception('Failed to fetch posts: $e');
    }
  }
}

2.3 数据持久化

2.3.1 SharedPreferences

dart 复制代码
class PreferencesService {
  static late SharedPreferences _prefs;

  static Future<void> init() async {
    _prefs = await SharedPreferences.getInstance();
  }

  // 存储数据
  static Future<bool> setString(String key, String value) async {
    return await _prefs.setString(key, value);
  }

  static Future<bool> setInt(String key, int value) async {
    return await _prefs.setInt(key, value);
  }

  // 读取数据
  static String? getString(String key) {
    return
相关推荐
牛奶3 小时前
HTTPS你不知道的事
前端·https·浏览器
extrao1 天前
🚀 Kea DHCP4 自动分配系统完整搭建
网络协议
恋猫de小郭1 天前
Amper 正式转正 Kotlin Toolchain ,Gradle 未来何去何从
android·前端·flutter
张风捷特烈1 天前
Flutter 类库大揭秘#02 | path_provider 各平台实现
前端·flutter
CSharp精选营1 天前
WebSocket 快速入门教程(附示例源码)
websocket·教程·csharp·实时通信·asp.net-core
TT_Close2 天前
别劝退了!5秒搞定 Flutter 鸿蒙 FVM 起跑线
flutter·harmonyos·visual studio code
你听得到112 天前
用户说 App 卡,但说不清在哪?我把 Flutter 监控 SDK 升级成了链路观测工作台
前端·flutter·性能优化
不做菜鸟的网工3 天前
BGP特性
网络协议
AlfredZhao3 天前
生产环境里,为什么不建议把普通端口直接暴露到公网?
linux·https·443·80
MrSYJ3 天前
TCP协议理解
后端·tcp/ip