我有两个模型,但它们没有公共id字段,但我需要过滤所有项目。我正在使用where
方法,正如我在文档中所读到的,这种方法可以帮助解决我的问题。但问题是,它只适用于两种型号中相同的id字段。如果我想通过不常见的字段进行筛选,该怎么办?
我看到了其他人为两个模型创建助手类并将它们合并到一个数组中的solitions,但问题是它应该具有两个数组的预定义大小,如果我尝试在CoffeeShop模型中添加另一个项目或在菜单中添加其他项目,它会给出关于数组长度的错误。
我的型号:
class CoffeeShop {
CoffeeShop({this.shopTitle, this.id});
int id;
final String shopTitle;
@override
String toString() => "CoffeeShop(shopTitle: $shopTitle)";
}
class CoffeeShopMenu {
int sid;
final String store;
CoffeeShopMenu({this.shopMenuTitle, this.store, this.sid});
final String shopMenuTitle;
@override
String toString() => "CoffeeShopMenu(shopMenuTitle: $shopMenuTitle)";
}
第一个屏幕的代码:
class _ExpState extends State<Exp> {
final List<CoffeeShop> coffeeShop = <CoffeeShop>[
CoffeeShop(id: 1, shopTitle: 'Strarbucks'),
CoffeeShop(id: 2,shopTitle: 'Dunkin doghnuts'),
CoffeeShop(id: 3,shopTitle: 'Subway'),
CoffeeShop(id: 4,shopTitle: 'MCCafe'),
CoffeeShop(id: 5,shopTitle: 'Coffee Shop'),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: Icon(
Icons.search,
color: Colors.white,
),
),
],
),
body: ListView.builder(
itemCount: coffeeShop.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(coffeeShop[index].shopTitle),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Exp1(
//here i want item to be filtered
sid: coffeeShop[index].id,
shopTitle: coffeeShop[index].shopTitle
)));
},
);
}),
);
}
}
第二个屏幕的代码:
class _Exp1State extends State<Exp1> {
final List<CoffeeShop> coffeeShop = <CoffeeShop>[
CoffeeShop(id: 1, shopTitle: 'Strarbucks'),
CoffeeShop(id: 2,shopTitle: 'Dunkin doghnuts'),
CoffeeShop(id: 3,shopTitle: 'Subway'),
CoffeeShop(id: 4,shopTitle: 'MCCafe'),
CoffeeShop(id: 5,shopTitle: 'Coffee Shop'),
];
final List<CoffeeShopMenu> coffeeMenu = <CoffeeShopMenu>[
CoffeeShopMenu(sid: 1, shopMenuTitle: 'Matcha'),
CoffeeShopMenu(sid: 1,shopMenuTitle: 'Matcha'),
CoffeeShopMenu(sid: 4,shopMenuTitle: 'Matcha'),
CoffeeShopMenu(sid: 4,shopMenuTitle: 'pie'),
CoffeeShopMenu(sid: 3,shopMenuTitle: 'sandwich'),
CoffeeShopMenu(sid: 4,shopMenuTitle: 'croissant'),
CoffeeShopMenu(sid: 5,shopMenuTitle: 'croissant A'),
CoffeeShopMenu(sid: 5,shopMenuTitle: 'croissant A'),
CoffeeShopMenu(sid: 2,shopMenuTitle: 'croissant'),
CoffeeShopMenu(sid: 2,shopMenuTitle: 'Latte'),
CoffeeShopMenu(sid: 4,shopMenuTitle: 'Latte'),
CoffeeShopMenu(sid: 3,shopMenuTitle: 'Latte'),
CoffeeShopMenu(sid: 5,shopMenuTitle: 'Latte'),
];
int index;
List<CoffeeShopMenu> get coffeeMenuTitle => coffeeMenu.where((element) => element.sid == coffeeShop[index].id).toList();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ListView.builder(itemCount: coffeeMenuTitle.length,itemBuilder: (context, index){
return ListTile(
title: Text(coffeeMenuTitle[index].shopMenuTitle),
);
}),
);
}
}
从您的代码中,我可以看到您的列表屏幕中一切都很好。但您并没有使用通过Shop列表页面中的构造函数发送的sid
值。
MaterialPageRoute(
builder: (context) => Exp1(
//Don't apply filter here for the sake of simplicity.
sid: coffeeShop[index].id, => This is not used
shopTitle: coffeeShop[index].shopTitle)));
在您的详细信息页面中,请执行以下操作。
定义构造函数
class Exp1 extends StatefulWidget {
final int sid;
final String shopTitle;
const Exp1({Key key, this.sid, this.shopTitle}) : super(key: key);
...
}
在<State>
中添加以下内容。
class _Exp1State extends State<Exp1> {
final List<CoffeeShopMenu> coffeeMenu = <CoffeeShopMenu>[
CoffeeShopMenu(sid: 1, shopMenuTitle: 'Matcha'),
CoffeeShopMenu(sid: 1, shopMenuTitle: 'Matcha'),
CoffeeShopMenu(sid: 4, shopMenuTitle: 'Matcha'),
CoffeeShopMenu(sid: 4, shopMenuTitle: 'pie'),
CoffeeShopMenu(sid: 3, shopMenuTitle: 'sandwich'),
CoffeeShopMenu(sid: 4, shopMenuTitle: 'croissant'),
CoffeeShopMenu(sid: 5, shopMenuTitle: 'croissant A'),
CoffeeShopMenu(sid: 5, shopMenuTitle: 'croissant A'),
CoffeeShopMenu(sid: 2, shopMenuTitle: 'croissant'),
CoffeeShopMenu(sid: 2, shopMenuTitle: 'Latte'),
CoffeeShopMenu(sid: 4, shopMenuTitle: 'Latte'),
CoffeeShopMenu(sid: 3, shopMenuTitle: 'Latte'),
CoffeeShopMenu(sid: 5, shopMenuTitle: 'Latte'),
];
List<CoffeeShopMenu> filteredCoffeeMenu = [];
根据initState
中的商店id筛选菜单
@override
void initState() {
super.initState();
filteredCoffeeMenu =
coffeeMenu.where((element) => element.sid == widget.sid).toList();
}
在ListViewBuilder
中使用filteredCoffeeMenu
ListView.builder(
itemCount: filteredCoffeeMenu.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(filteredCoffeeMenu[index].shopMenuTitle),
);
}),
编辑:如果要从API获取列表,请使用FutureBuilder
获取API响应,然后执行筛选过程,而不是在initState
中执行如果有任何疑问,请告知:(编码快乐!!