在本篇文章中,我们将通过一个实际的 Flutter 应用来综合运用最近学到的知识,包括保存到数据库、进行 HTTP 请求等。我们将开发一个简单的天气应用,可以根据用户输入的城市名获取该城市的天气信息,并将用户查询的城市列表保存到本地数据库中。
第一步:需求分析和设计
1. 确定项目目标
我们的目标是开发一个天气应用,用户可以在应用中输入城市名,然后获取该城市的天气信息。
2. 设计界面
我们的应用包含两个页面:主页面用于输入城市名,显示天气信息,以及查询历史记录页面用于显示用户查询的城市列表。
第二步:开发
1. 创建 Flutter 项目
首先,在命令行中创建一个新的 Flutter 项目:
flutter create my_first_flutter_app
然后,进入项目目录:
cd my_first_flutter_app
2. 编码实现
a. 创建页面和路由
在 lib 文件夹中创建两个文件:home_page.dart、history_page.dart。
home_page.dart:
import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; class HomePage extends StatefulWidget { @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { String city = ''; String weather = ''; void getWeather() async { final response = await http.get(Uri.parse( 'https://api.openweathermap.org/data/2.5/weather?q=$city&appid=YOUY_API_KEY')); if (response.statusCode == 200) { final data = jsonDecode(response.body); setState(() { weather = 'Temperature: ${data['main']['temp']}°C, Weather: ${data['weather'][0]['main']}'; }); } else { setState(() { weather = 'Failed to get weather data'; }); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Weather App'), ), body: Padding( padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ TextField( onChanged: (value) { setState(() { city = value; }); }, decoration: InputDecoration(labelText: 'City Name'), ), ElevatedButton( onPressed: () { getWeather(); }, child: Text('Get Weather'), ), SizedBox(height: 20), Text( weather, style: TextStyle(fontSize: 18), ), ], ), ), ); } }
history_page.dart:
import 'package:flutter/material.dart'; import 'package:my_first_flutter_app/database_helper.dart'; import 'package:my_first_flutter_app/city.dart'; class HistoryPage extends StatefulWidget { @override _HistoryPageState createState() => _HistoryPageState(); } class _HistoryPageState extends State<HistoryPage> { List<City> cities = []; @override void initState() { super.initState(); fetchCities(); } void fetchCities() async { final dbHelper = DatabaseHelper.instance; final allRows = await dbHelper.queryAllRows(); setState(() { cities = allRows.map((row) => City.fromMap(row)).toList(); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Search History'), ), body: ListView.builder( itemCount: cities.length, itemBuilder: (context, index) { final city = cities[index]; return ListTile( title: Text(city.name), subtitle: Text('Weather: ${city.weather}'), ); }, ), ); } }
在 main.dart 文件中,设置路由:
import 'package:flutter/material.dart'; import 'package:my_first_flutter_app/home_page.dart'; import 'package:my_first_flutter_app/history_page.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( initialRoute: '/', routes: { '/': (context) => HomePage(), '/history': (context) => HistoryPage(), }, ); } }
b. 实现数据库功能
我们将使用 SQLite 来保存用户查询的城市列表。在 lib 文件夹中创建新的文件 city.dart、database_helper.dart,用于创建和管理数据库。
city.dart
class City { int id; String name; String weather; City({this.id = 0, required this.name, required this.weather}); Map<String, dynamic> toMap() { return {'id': id, 'name': name, 'weather': weather}; } City.fromMap(Map<String, dynamic> map) : id = map['id'], name = map['name'], weather = map['weather']; }
database_helper.dart
import 'package:sqflite/sqflite.dart'; import 'package:path/path.dart'; import 'package:my_first_flutter_app/city.dart'; class DatabaseHelper { static final _databaseName = 'weather_database.db'; static final _databaseVersion = 1; static final table = 'cities'; static final columnId = '_id'; static final columnName = 'name'; static final columnWeather = 'weather'; DatabaseHelper._privateConstructor(); static final DatabaseHelper instance = DatabaseHelper._privateConstructor(); static Database? _database; Future<Database?> get database async { if (_database != null) return _database; _database = await _initDatabase(); return _database; } _initDatabase() async { String path = join(await getDatabasesPath(), _databaseName); return await openDatabase(path, version: _databaseVersion, onCreate: _onCreate); } Future<void> _onCreate(Database db, int version) async { await db.execute(''' CREATE TABLE $table ( $columnId INTEGER PRIMARY KEY, $columnName TEXT NOT NULL, $columnWeather TEXT NOT NULL ) '''); } Future<int> insert(City city) async { Database? db = await instance.database; return await db?.insert(table, city.toMap()) ?? 0; } Future<List<Map<String, dynamic>>> queryAllRows() async { Database? db = await instance.database; return await db?.query(table) ?? []; } }
第三步:测试
1. 运行应用
使用以下命令在模拟器或真机上运行应用:
flutter run
检查应用是否按预期工作,并确保你可以查询城市的天气,并查看查询历史记录。

2. 进行单元测试和集成测试
除了手动测试之外,我们还应该进行单元测试和集成测试来确保应用的稳定性和正确性。在 Flutter 中,我们可以使用 flutter_test 包进行测试。
第四步:发布
当我们完成了开发和测试之后,就可以考虑发布应用了。在发布之前,我们需要完成以下几个步骤:
1. 生成 APK 或 IPA 文件
使用以下命令生成 APK 文件(Android)或 IPA 文件(iOS):
flutter build apk flutter build ios
2. 申请开发者账号
如果你要发布到应用商店(如 Google Play 或 App Store),你需要申请开发者账号,并遵循相应的发布指南。
3. 提交应用
一旦你准备好了 APK 或 IPA 文件,并且已经申请了开发者账号,你可以提交应用到相应的应用商店进行审核和发布。
总结
在本篇文章中,我们通过一个简单的天气应用示例,综合运用了最近学到的知识,包括保存到数据库、进行 HTTP 请求等。通过这个实战项目,你可以更加深入地了解 Flutter 应用的开发流程,并掌握实际项目中的常用技术和最佳实践。
希望这个实战项目对你有所帮助。如果你有任何问题或需要进一步的指导,请随时向我询问。祝你在 Flutter 开发的道路上取得成功!
本文由mdnice多平台发布