Flutter实现列表点击跳转并填充新页面的方案咨询
Flutter 生日派对宾客列表+详情页实现思路
1. 数据库准备与依赖配置
- 用Flutter常用的
sqflite插件操作SQLite数据库,先在pubspec.yaml里添加依赖:dependencies: sqflite: ^2.3.0 path: ^1.8.3 # 处理数据库文件路径 - 创建宾客数据模型类,对应数据库表字段,方便数据转换:
class Guest { final int id; final String name; final String avatarThumbPath; // 缩略图路径(本地/网络) final String avatarLargePath; // 大图路径 final int age; final String contact; Guest({ required this.id, required this.name, required this.avatarThumbPath, required this.avatarLargePath, required this.age, required this.contact, }); // 把数据库查询返回的Map转成Guest对象 factory Guest.fromMap(Map<String, dynamic> map) { return Guest( id: map['id'], name: map['name'], avatarThumbPath: map['avatar_thumb'], avatarLargePath: map['avatar_large'], age: map['age'], contact: map['contact'], ); } } - 写数据库操作工具类,封装基础查询方法:
class DBHelper { static Database? _database; // 获取数据库实例 static Future<Database> get database async { if (_database != null) return _database!; _database = await _initDB(); return _database!; } // 初始化打开数据库(你的数据库已创建,这里直接打开即可) static Future<Database> _initDB() async { String path = await getDatabasesPath(); path = join(path, 'party_guests.db'); return await openDatabase(path, version: 1); } // 查询所有宾客数据 static Future<List<Guest>> getAllGuests() async { final db = await database; final List<Map<String, dynamic>> maps = await db.query('guests'); return List.generate(maps.length, (i) => Guest.fromMap(maps[i])); } // 根据ID查询单个宾客详情 static Future<Guest?> getGuestById(int id) async { final db = await database; final List<Map<String, dynamic>> maps = await db.query( 'guests', where: 'id = ?', whereArgs: [id], ); return maps.isNotEmpty ? Guest.fromMap(maps.first) : null; } }
2. 宾客列表页实现
- 用
StatefulWidget实现,异步加载数据库数据:class GuestListPage extends StatefulWidget { const GuestListPage({super.key}); @override State<GuestListPage> createState() => _GuestListPageState(); } class _GuestListPageState extends State<GuestListPage> { List<Guest> _guests = []; @override void initState() { super.initState(); _loadGuests(); } // 从数据库加载宾客列表 Future<void> _loadGuests() async { final guests = await DBHelper.getAllGuests(); setState(() => _guests = guests); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('生日派对宾客')), body: ListView.builder( itemCount: _guests.length, itemBuilder: (context, index) { final guest = _guests[index]; return InkWell( // 点击跳转详情页,传递宾客ID onTap: () => Navigator.push( context, MaterialPageRoute( builder: (context) => GuestDetailPage(guestId: guest.id), ), ), child: Padding( padding: const EdgeInsets.all(12.0), child: Row( children: [ // 缩略图(本地图换Image.asset/Image.file) ClipRRect( borderRadius: BorderRadius.circular(8), child: Image.network( guest.avatarThumbPath, width: 60, height: 60, fit: BoxFit.cover, ), ), const SizedBox(width: 12), Text(guest.name, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w500)), ], ), ), ); }, ), ); } }
3. 宾客详情页实现
- 接收列表页传递的ID,异步查询并展示详情:
class GuestDetailPage extends StatefulWidget { final int guestId; const GuestDetailPage({super.key, required this.guestId}); @override State<GuestDetailPage> createState() => _GuestDetailPageState(); } class _GuestDetailPageState extends State<GuestDetailPage> { Guest? _guest; @override void initState() { super.initState(); _loadGuestDetail(); } // 加载单个宾客详情 Future<void> _loadGuestDetail() async { final guest = await DBHelper.getGuestById(widget.guestId); setState(() => _guest = guest); } @override Widget build(BuildContext context) { if (_guest == null) { return const Scaffold(body: Center(child: CircularProgressIndicator())); } final guest = _guest!; return Scaffold( appBar: AppBar(title: Text(guest.name)), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 宾客大图 Center( child: ClipRRect( borderRadius: BorderRadius.circular(12), child: Image.network( guest.avatarLargePath, width: 200, height: 200, fit: BoxFit.cover, ), ), ), const SizedBox(height: 20), Text('姓名: ${guest.name}', style: const TextStyle(fontSize: 18)), const SizedBox(height: 8), Text('年龄: ${guest.age}岁', style: const TextStyle(fontSize: 18)), const SizedBox(height: 8), Text('联系方式: ${guest.contact}', style: const TextStyle(fontSize: 18)), ], ), ), ); } }
4. 可选:全局路由配置
- 若想简化跳转逻辑,可在
MaterialApp中提前配置路由:MaterialApp( initialRoute: '/', routes: { '/': (context) => const GuestListPage(), '/detail': (context) { final args = ModalRoute.of(context)!.settings.arguments as int; return GuestDetailPage(guestId: args); }, }, ) - 跳转时改为:
Navigator.pushNamed(context, '/detail', arguments: guest.id);
内容的提问来源于stack exchange,提问作者Diogo Boëchat
相关产品推荐
相关产品推荐

