学习Flutter:搭建第一个 Flutter 应用

引言

曾几何时,我们还在为 Android 和 iOS 各写一套 UI 而头疼,做一个需求像是两家公司在竞争。但 Flutter 的出现,改变了这一切。它让跨平台开发变得可能,让一个程序员的代码可以同时运行在多个设备上,省时省力,效果炸裂。

本篇文章就是为了让更多开发者轻松起步,快速搭建第一个 Flutter 应用。我会从零开始,带你搭建环境,解析原理,再到实战案例,最后深度探讨 Flutter 的优缺点、性能评估,以及未来趋势。想学 Flutter 的朋友,这篇文章一定要收藏!


一、背景

Flutter 是 Google 开发的一款跨平台 UI 框架,支持 Android、iOS、Web 和桌面端开发。它基于 Dart 语言,使用 Skia 渲染引擎,实现高性能、流畅的 UI 体验。相比传统的原生开发,Flutter 具备以下特点:

  1. 一套代码,多端运行------一次开发,多端使用,减少重复劳动。
  2. 性能强悍------Flutter 使用自己的渲染引擎,性能逼近原生。
  3. 热重载(Hot Reload)------改代码不用重启 App,开发效率大大提升!
  4. 丰富的 UI 组件------Material 和 Cupertino 组件齐全,想做 iOS 风格还是 Android 风格,一行代码切换!
  5. 生态越来越强------Flutter 不仅仅是手机 App,现在还能跑在 Web 和桌面端,简直万能!

Flutter 就像编程界的瑞士军刀,给你带来意想不到的便捷。


二、概念

Flutter 的核心是Widget(组件),一切 UI 都是 Widget 组成的。你可以理解为乐高积木,页面上的任何一个按钮、文字、布局,甚至整个应用,都是一个个 Widget 组合而成的。

Flutter 的工作流程如下:

  1. Dart 代码:开发者写 Dart 代码,描述 UI 和逻辑。
  2. Flutter Framework:Flutter 框架解析代码,组织 Widget 树。
  3. Skia 引擎:Flutter 自带的 Skia 引擎负责绘制 UI,并传递给 GPU 渲染。
  4. 原生平台:最终通过 Android 和 iOS 的系统接口,把 UI 显示出来。

Flutter 的这种架构,让它可以做到跨平台一致性,同时保证流畅度,做到真正的"所见即所得"


三、实现

1. 环境搭建

必备工具

  • Flutter SDK
  • Dart SDK(Flutter 自带)
  • Android Studio 或 VS Code(推荐)
  • Android 或 iOS 模拟器
  • 电脑(Windows/Mac/Linux 都可)
2. 安装 Flutter
bash 复制代码
# 下载 Flutter SDK
git clone https://github.com/flutter/flutter.git -b stable
# 配置环境变量
export PATH="$PATH:`pwd`/flutter/bin"
# 检查安装情况
flutter doctor

如果 flutter doctor 输出全绿,说明安装成功!

3. 创建项目
bash 复制代码
flutter create my_first_app
cd my_first_app
flutter run

如果看到 "Hello, world!",恭喜你,Flutter 成功跑起来了!


四、项目实战

好的!我将提供 3 个 Flutter 实战项目,包括详细的代码和实现过程,每个项目都能直接在编译工具上运行。


项目 1:计数器应用(Hello World 进阶版)

目标

创建一个 计数器应用,用户可以点击按钮增加计数,并能重置计数。

主要技术点

  • StatefulWidget 组件的使用
  • setState 更新 UI
  • Material UI 基本布局

完整代码

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: CounterScreen(),
    );
  }
}

class CounterScreen extends StatefulWidget {
  @override
  _CounterScreenState createState() => _CounterScreenState();
}

class _CounterScreenState extends State<CounterScreen> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  void _resetCounter() {
    setState(() {
      _counter = 0;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Flutter 计数器")),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text("当前计数:", style: TextStyle(fontSize: 20)),
            Text("$_counter", style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold)),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(onPressed: _incrementCounter, child: Text("增加")),
                SizedBox(width: 10),
                ElevatedButton(onPressed: _resetCounter, child: Text("重置")),
              ],
            )
          ],
        ),
      ),
    );
  }
}

运行效果

  1. 点击 "增加" 按钮,计数值 +1
  2. 点击 "重置" 按钮,计数归零

项目 2:待办事项(Todo)应用

目标

实现一个 待办事项(Todo)应用,支持:

  • 添加任务
  • 删除任务
  • 持久化存储

主要技术点

  • ListView 列表
  • TextEditingController 处理输入
  • SharedPreferences 存储数据

完整代码

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: TodoScreen(),
    );
  }
}

class TodoScreen extends StatefulWidget {
  @override
  _TodoScreenState createState() => _TodoScreenState();
}

class _TodoScreenState extends State<TodoScreen> {
  List<String> _tasks = [];
  TextEditingController _controller = TextEditingController();

  @override
  void initState() {
    super.initState();
    _loadTasks();
  }

  void _loadTasks() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    setState(() {
      _tasks = (prefs.getStringList('tasks') ?? []);
    });
  }

  void _saveTasks() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setStringList('tasks', _tasks);
  }

  void _addTask() {
    if (_controller.text.isEmpty) return;
    setState(() {
      _tasks.add(_controller.text);
      _controller.clear();
    });
    _saveTasks();
  }

  void _removeTask(int index) {
    setState(() {
      _tasks.removeAt(index);
    });
    _saveTasks();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("待办事项")),
      body: Column(
        children: [
          Padding(
            padding: EdgeInsets.all(10),
            child: Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: _controller,
                    decoration: InputDecoration(hintText: "输入任务"),
                  ),
                ),
                IconButton(icon: Icon(Icons.add), onPressed: _addTask),
              ],
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: _tasks.length,
              itemBuilder: (context, index) {
                return ListTile(
                  title: Text(_tasks[index]),
                  trailing: IconButton(
                    icon: Icon(Icons.delete, color: Colors.red),
                    onPressed: () => _removeTask(index),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

运行效果

  1. 输入任务后点击 "+" 按钮,任务会加入列表
  2. 点击任务右侧的 垃圾桶 按钮,即可删除任务
  3. 关闭应用后再次打开,任务仍然存在(已存储)

项目 3:天气预报应用

目标

实现一个 天气预报应用,展示某个城市的天气情况。

主要技术点

  • http 请求 API
  • json 解析数据
  • FutureBuilder 处理异步数据

完整代码

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: WeatherScreen(),
    );
  }
}

class WeatherScreen extends StatefulWidget {
  @override
  _WeatherScreenState createState() => _WeatherScreenState();
}

class _WeatherScreenState extends State<WeatherScreen> {
  String city = "Shenzhen";
  Map<String, dynamic>? weatherData;

  Future<void> fetchWeather() async {
    final apiKey = "YOUR_API_KEY"; // 需替换为自己的 API Key
    final url = Uri.parse("https://api.openweathermap.org/data/2.5/weather?q=$city&appid=$apiKey&units=metric");
    
    final response = await http.get(url);
    if (response.statusCode == 200) {
      setState(() {
        weatherData = json.decode(response.body);
      });
    }
  }

  @override
  void initState() {
    super.initState();
    fetchWeather();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("天气预报")),
      body: Center(
        child: weatherData == null
            ? CircularProgressIndicator()
            : Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text("${weatherData!['name']} 的天气", style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
                  Text("${weatherData!['main']['temp']}°C", style: TextStyle(fontSize: 40)),
                  Text("${weatherData!['weather'][0]['description']}", style: TextStyle(fontSize: 20)),
                ],
              ),
      ),
    );
  }
}

运行效果

  1. 启动应用后,会自动获取深圳的天气数据
  2. 数据显示:城市名称、温度、天气描述
  3. 数据源 :调用 OpenWeatherMap API 获取实时天气

这三个项目展示了 Flutter 的核心开发能力,你可以在此基础上扩展功能,比如:

  • 计数器 App 添加计时器功能
  • Todo App 使用数据库存储数据
  • 天气 App 增加定位功能

五、问题解决,容易踩的坑

  1. 安装 Flutter 时报错:可能是网络问题,可以尝试 VPN 或者换清华源。
  2. iOS 模拟器不能运行:需要 macOS 和 Xcode,Windows 用户无解。
  3. 热重载失效:可能是 StatefulWidget 没有正确更新 setState()。
  4. 插件不兼容:有些插件可能不支持 Web 或桌面端,要查看官方文档。

六、优缺点

优点

  • 开发效率高,热重载太爽了!
  • 跨平台一致性好,UI 统一。
  • 生态越来越强,社区活跃。

缺点

  • 体积较大,Flutter App 相比原生略胖。
  • iOS 支持相对弱,某些系统 API 需要手动桥接。
  • Dart 生态较小,不如 JavaScript 和 Python 热门。

七、性能

Flutter 的渲染性能比 React Native 高,但比原生略低。在 60FPS 条件下,Flutter 的 CPU 负载大约是原生的 1.2 倍,内存占用稍高。不过,得益于 Skia 引擎,Flutter 能在大多数设备上保持流畅度。


八、展望

Google 正在加速 Flutter 的发展,未来会在桌面端和 Web 端更加强大。同时,Flutter 3.0 可能会带来更低的内存占用、更高的性能,以及更好的插件生态。


总结

Flutter 是一个极具潜力的跨平台开发框架,它的出现降低了开发成本,提高了开发效率。如果你还没用过 Flutter,不妨试试,可能会爱上它!


参考资料

🚀 欢迎关注 GongZhongHao,码农的乌托邦,程序员的精神家园! 🚀

相关推荐
小杜不吃糖1 小时前
llama源码学习·model.py[6]TransformerBlock类
学习·llama
云上艺旅5 小时前
K8S学习之基础四十七:k8s中部署fluentd
学习·云原生·容器·kubernetes
网络安全指导员8 小时前
威胁驱动的网络安全方法论
开发语言·学习·安全·web安全·php
Leo来编程8 小时前
Python学习第二十三天
python·学习
书弋江山9 小时前
flutter 自定义控件RenderObjectWidget使用
前端·javascript·flutter
郭逍遥10 小时前
GZCTF平台搭建及题目上传
笔记·学习·ubuntu·docker·容器
吱屋猪_10 小时前
MyBatis 学习经验分享
经验分享·学习·mybatis
帅次12 小时前
Flutter 输入组件 Radio 详解
android·flutter·ios·kotlin·android studio
落笔画忧愁e12 小时前
数据通信学习笔记之OSPF其他内容1
笔记·学习
GHL28427109013 小时前
mysql学习-B+树相关问题
b树·学习·mysql