Flutter如何将多列表抽离到独立文件后在对应页面正常导入使用
实现步骤
1. 抽离独立数据文件
新建lib/data/country_data.dart,存放所有列表常量、数据模型,避免在业务页面的initState中重复初始化导致冲突:
import 'package:flutter/material.dart'; // 数据模型类,Dart规范要求类名使用大驼峰 class GenelSiralama { final String bayrak; final String ulkeadi; final String nufus; final Widget yolu; GenelSiralama(this.bayrak, this.ulkeadi, this.nufus, this.yolu); } // 分类列表 const List<String> listItem = [ "Genel Sıralama", "Nüfusa Göre", "Savunma Bütçesine Göre", "Tank Sayısına Göre", "Uçak Sayısına Göre", "Donanma Gücüne Göre", "Toprak Büyüklüğüne Göre", "Petrol Rezervlerine Göre", ]; // 总排名列表 const List<GenelSiralama> genelsiralamaList = [ GenelSiralama( "assets/anasayfa/bayraklar/amerika.png", "Amerika Birleşik Devletleri", "329,256,465", Almanya(), // 对应跳转页面类也请遵循大驼峰命名规范 ), GenelSiralama( "assets/anasayfa/bayraklar/rusya.png", "Rusya", "142,122,776", Almanya(), ), // 后续可直接在此添加更多总排名数据 ]; // 第二个列表(例:人口排名列表,所有其他分类列表都可在此独立定义) const List<GenelSiralama> nufusSiralamaList = [ // 对应分类的列表数据 ];
2. 抽离复用列表组件
新建lib/widget/country_rank_list.dart,把ListView.builder逻辑独立成可传参的通用组件:
import 'package:flutter/material.dart'; import '../data/country_data.dart'; class CountryRankList extends StatelessWidget { // 接收列表作为入参,传不同列表即可展示不同内容 final List<GenelSiralama> rankList; const CountryRankList({super.key, required this.rankList}); @override Widget build(BuildContext context) { return ListView.builder( scrollDirection: Axis.vertical, shrinkWrap: true, physics: const ScrollPhysics(), itemCount: rankList.length, itemBuilder: (context, index) { final item = rankList[index]; return Card( elevation: 4.0, child: Center( child: Column( children: [ GestureDetector( child: InkWell( onDoubleTap: () => Navigator.push( context, MaterialPageRoute(builder: (context) => item.yolu), ), onTap: () => ScaffoldMessenger.of(context).showSnackBar( SnackBar( backgroundColor: Colors.black54, content: Text( "${item.ulkeadi} Sayfasına Gitmek için Çift Tıklayın", style: const TextStyle( color: Colors.white, fontSize: 15, fontWeight: FontWeight.bold), ), ), ), onTapCancel: () { ScaffoldMessenger.of(context).showSnackBar(SnackBar( backgroundColor: Colors.black54, content: Text( 'Hay Aksi Tamda ${item.ulkeadi} Sayfasına Gidiyordun', style: const TextStyle( color: Colors.white, fontSize: 15, fontWeight: FontWeight.bold), ))); }, child: Image.asset(item.bayrak), ), ), ListTile( leading: const Icon( Icons.people, size: 35, color: Colors.red, ), title: Text( item.ulkeadi, style: const TextStyle(fontWeight: FontWeight.bold), ), subtitle: Text( "Nufüs : ${item.nufus}", ), trailing: CircleAvatar( backgroundColor: Colors.teal, child: Text( (index + 1).toString(), style: const TextStyle(color: Colors.white), ), ), ), ], ), ), ); }, ); } }
3. 业务页面导入使用
在你原来的StatefulWidget页面直接导入两个文件即可,不需要在当前页面的initState初始化任何列表,不会出现多列表导入冲突:
import 'package:flutter/material.dart'; import 'data/country_data.dart'; import 'widget/country_rank_list.dart'; class YourOriginPage extends StatefulWidget { const YourOriginPage({super.key}); @override State<YourOriginPage> createState() => _YourOriginPageState(); } class _YourOriginPageState extends State<YourOriginPage> { @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ // 展示总排名列表 Expanded(child: CountryRankList(rankList: genelsiralamaList)), // 要展示第二个列表直接传对应参数即可 // Expanded(child: CountryRankList(rankList: nufusSiralamaList)), ], ), ); } }
原报错原因说明
之前导入第二个列表报错,是因为把多个列表的初始化逻辑都耦合在当前页面的initState中,或是不同导出文件存在同名变量/方法,按上述方案抽离后所有列表都是独立的常量,互不影响,直接引用即可。
内容的提问来源于stack exchange,提问作者Barış Çapar
相关产品推荐
相关产品推荐

