在本篇文章中,我们将通过一个实际的 Flutter 应用来综合运用最近学到的知识,包括保存到数据库、进行 HTTP 请求等。我们将开发一个简单的天气应用,可以根据用户输入的城市名获取该城市的天气信息,并将用户查询的城市列表保存到本地数据库中。
第一步:需求分析和设计1. 确定项目目标我们的目标是开发一个天气应用,用户可以在应用中输入城市名,然后获取该城市的天气信息。
2. 设计界面我们的应用包含两个页面:主页面用于输入城市名,显示天气信息,以及查询历史记录页面用于显示用户查询的城市列表。
(资料图片)
首先,在命令行中创建一个新的 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 { 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 { List 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 toMap() { return {"id": id, "name": name, "weather": weather}; } City.fromMap(Map 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 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 _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 insert(City city) async { Database? db = await instance.database; return await db?.insert(table, city.toMap()) ?? 0; } Future>> 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 apkflutter build ios
2. 申请开发者账号如果你要发布到应用商店(如 Google Play 或 App Store),你需要申请开发者账号,并遵循相应的发布指南。
3. 提交应用一旦你准备好了 APK 或 IPA 文件,并且已经申请了开发者账号,你可以提交应用到相应的应用商店进行审核和发布。
总结在本篇文章中,我们通过一个简单的天气应用示例,综合运用了最近学到的知识,包括保存到数据库、进行 HTTP 请求等。通过这个实战项目,你可以更加深入地了解 Flutter 应用的开发流程,并掌握实际项目中的常用技术和最佳实践。
希望这个实战项目对你有所帮助。如果你有任何问题或需要进一步的指导,请随时向我询问。祝你在 Flutter 开发的道路上取得成功!
本文由mdnice多平台发布