
🎯 到目前为止,你已经掌握了:
现在,是时候把这些知识整合成一个小型 综合 App,从零到可运行。
功能需求:
lib/ ├─ main.dart ├─ pages/ │ ├─ login_page.dart │ ├─ home_page.dart │ └─ detail_page.dart └─ utils/ └─ storage_util.dart
📌 分工:
- pages → 页面
- utils → 工具类(本地存储)
- main.dart → 路由入口
---
## 三、工具类:本地存储
```dart
import 'package:shared_preferences/shared_preferences.dart';
class StorageUtil {
static Future<void> saveUsername(String username) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString('username', username);
}
static Future<String?> getUsername() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString('username');
}
static Future<void> clear() async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove('username');
}
}
import 'package:flutter/material.dart';
import '../utils/storage_util.dart';
class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final _formKey = GlobalKey<FormState>();
final TextEditingController _usernameController = TextEditingController();
final TextEditingController _passwordController = TextEditingController();
void _login() async {
if (_formKey.currentState!.validate()) {
await StorageUtil.saveUsername(_usernameController.text);
Navigator.pushReplacementNamed(context, '/home');
}
}
@override
void dispose() {
_usernameController.dispose();
_passwordController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('登录')),
body: Padding(
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: _usernameController,
decoration: InputDecoration(labelText: '用户名'),
validator: (value) => value!.isEmpty ? '请输入用户名' : null,
),
SizedBox(height: 10),
TextFormField(
controller: _passwordController,
decoration: InputDecoration(labelText: '密码'),
obscureText: true,
validator: (value) => value!.length < 6 ? '密码至少6位' : null,
),
SizedBox(height: 20),
ElevatedButton(onPressed: _login, child: Text('登录')),
],
),
),
),
);
}
}
import 'package:flutter/material.dart';
import '../utils/storage_util.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
List<Map> _items = List.generate(
20, (index) => {'id': index, 'title': '条目 $index'});
void _logout() async {
await StorageUtil.clear();
Navigator.pushReplacementNamed(context, '/');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('首页列表'),
actions: [
IconButton(onPressed: _logout, icon: Icon(Icons.logout)),
],
),
body: ListView.builder(
itemCount: _items.length,
itemBuilder: (context, index) {
final item = _items[index];
return ListTile(
title: Text(item['title']),
trailing: Icon(Icons.chevron_right),
onTap: () {
Navigator.pushNamed(context, '/detail', arguments: item);
},
);
},
),
);
}
}
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class DetailPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final args = ModalRoute.of(context)!.settings.arguments as Map;
final id = args['id'];
final title = args['title'];
return Scaffold(
appBar: AppBar(title: Text(title)),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Hero(
tag: 'item_$id',
child: FlutterLogo(size: 100),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () async {
final url = Uri.parse('https://flutter.dev');
if (await canLaunchUrl(url)) {
await launchUrl(url);
}
},
child: Text('访问 Flutter 官网'),
),
],
),
),
);
}
}
📌 功能:
import 'package:flutter/material.dart';
import 'pages/login_page.dart';
import 'pages/home_page.dart';
import 'pages/detail_page.dart';
import 'utils/storage_util.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final username = await StorageUtil.getUsername();
runApp(MyApp(initialRoute: username == null ? '/' : '/home'));
}
class MyApp extends StatelessWidget {
final String initialRoute;
MyApp({required this.initialRoute});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '综合实战 App',
initialRoute: initialRoute,
routes: {
'/': (context) => LoginPage(),
'/home': (context) => HomePage(),
'/detail': (context) => DetailPage(),
},
);
}
}
📌 功能:
🎯 这就是一个 从零基础到可运行的小型 App 的完整流程
你已经学会:
📌 到这里为止:
Flutter 零基础入门系列完整闭环 ✅
现在,你已经可以独立开发一个简单 Flutter App,并为后续进阶学习打下坚实基础! 🎉