在 ListView 上应用多个条件过滤器
apply multiple conditional filters on a ListView
我是一名新的 flutter 开发人员,想在我的列表中使用多个过滤器。
我正在使用 ListView :
ListView.builder(
itemBuilder: (ctx, index) =>
MealCard(_customList[index]),
itemCount: _customList.length,
),
和我的膳食 class 具有以下属性:
Meal {
final String id,
final String title,
final String imgUrl,
final bool isLowCalorie,
final bool isVegan,
final bool isBreakfat,
final bool isDinner,
final bool isLunch}
我想根据 class 中包含的布尔值应用不同的过滤器;我有一些看起来像这样的方法:
List<Meal> get breakfastFilter {
return _meals.where((element) => element.isBreakfast).toList();
}
List<Meal> get lunchFilter {
return _meals.where((element) => element.isLunch).toList();
}
List<Meal> get dinnerFilter {
return _meals.where((element) => element.isDinner).toList();
但是这些方法允许我创建一个列表,如果我想一起添加额外的过滤器并创建两个列表的组合怎么办。
你可以这样做:
bool filterItem(element){
return element.isVegan&&element.isBreakfat;
}
_meals.where((element) => filterItem(element)).toList();
有很多方法可以做到这一点,但您可以尝试将布尔值与可选参数结合使用,如下所示:
getMealFilter(_meals,
{bool lookForBreakfast = false,
bool lookForVegan = false,
bool lookForLunch = false}) {
return _meals
.where((element) =>
(lookForBreakfast && element.isBreakfast) ||
(lookForVegan && element.isBreakfast) ||
(lookForLunch && element.isLunch))
.toList();
}
我只放了 3 个过滤器,但您可以轻松添加其余部分。这是如何工作的,例如,如果 lookForBreakfast
为假,则忽略 element.isBreakfast
。 (false 和 something 总是 false),其他参数依此类推。
我知道我迟到了,所以让我来表彰一下吧。我会稍微重构它以支持多个过滤器,否则您不会预先知道将应用多少个过滤器。
我会创建一个名为 MealType:
的枚举
enum MealType {
none,
isLowCalorie,
isVegan,
isBreakfast,
isDinner,
isLunch
}
重构 class 以获取 MealType 值的列表:
class Meal {
final String? id;
final String? title;
final String? imgUrl;
final List<MealType>? mealTypeFilter;
Meal({ this.id, this.title, this.imgUrl, this.mealTypeFilter });
}
数据将如下所示:
List<Meal> meals = [
Meal(
id: '1001',
title: 'Pancakes',
imgUrl: '',
mealTypeFilter: [
MealType.isBreakfast
]
),
Meal(
id: '1002',
title: 'Chicken Wings',
imgUrl: '',
mealTypeFilter: [
MealType.isLunch
]
),
Meal(
id: '1003',
title: 'Yogurt',
imgUrl: '',
mealTypeFilter: [
MealType.isLowCalorie,
MealType.isBreakfast,
MealType.isVegan
]
)
];
我会在 Set 中收集应用的过滤器以避免重复,并过滤餐食 mealTypeFilter 集合是否包含任何应用的过滤器:
Set<MealType> appliedFilters = {};
List<Meal> filteredList = [];
List<Meal> getFilteredList() {
if (appliedFilters.isEmpty) {
return meals;
}
return meals.where((m) => m.mealTypeFilter!.any((f) => appliedFilters.contains(f))).toList();
}
当我触发包含要应用的过滤器的按钮并填充 时,每次在构建方法中我都会调用 getFilteredList() 方法filteredList 我用它来渲染 ListView 结果:
@override
Widget build(BuildContext context) {
filteredList = getFilteredList();
// rest of the code here
}
请参阅 Gist 了解完整代码,并通过 DartPad 运行 查看它的实际效果,如下所示:
希望这能奏效。
我是一名新的 flutter 开发人员,想在我的列表中使用多个过滤器。 我正在使用 ListView :
ListView.builder(
itemBuilder: (ctx, index) =>
MealCard(_customList[index]),
itemCount: _customList.length,
),
和我的膳食 class 具有以下属性:
Meal {
final String id,
final String title,
final String imgUrl,
final bool isLowCalorie,
final bool isVegan,
final bool isBreakfat,
final bool isDinner,
final bool isLunch}
我想根据 class 中包含的布尔值应用不同的过滤器;我有一些看起来像这样的方法:
List<Meal> get breakfastFilter {
return _meals.where((element) => element.isBreakfast).toList();
}
List<Meal> get lunchFilter {
return _meals.where((element) => element.isLunch).toList();
}
List<Meal> get dinnerFilter {
return _meals.where((element) => element.isDinner).toList();
但是这些方法允许我创建一个列表,如果我想一起添加额外的过滤器并创建两个列表的组合怎么办。
你可以这样做:
bool filterItem(element){
return element.isVegan&&element.isBreakfat;
}
_meals.where((element) => filterItem(element)).toList();
有很多方法可以做到这一点,但您可以尝试将布尔值与可选参数结合使用,如下所示:
getMealFilter(_meals,
{bool lookForBreakfast = false,
bool lookForVegan = false,
bool lookForLunch = false}) {
return _meals
.where((element) =>
(lookForBreakfast && element.isBreakfast) ||
(lookForVegan && element.isBreakfast) ||
(lookForLunch && element.isLunch))
.toList();
}
我只放了 3 个过滤器,但您可以轻松添加其余部分。这是如何工作的,例如,如果 lookForBreakfast
为假,则忽略 element.isBreakfast
。 (false 和 something 总是 false),其他参数依此类推。
我知道我迟到了,所以让我来表彰一下吧。我会稍微重构它以支持多个过滤器,否则您不会预先知道将应用多少个过滤器。
我会创建一个名为 MealType:
的枚举enum MealType {
none,
isLowCalorie,
isVegan,
isBreakfast,
isDinner,
isLunch
}
重构 class 以获取 MealType 值的列表:
class Meal {
final String? id;
final String? title;
final String? imgUrl;
final List<MealType>? mealTypeFilter;
Meal({ this.id, this.title, this.imgUrl, this.mealTypeFilter });
}
数据将如下所示:
List<Meal> meals = [
Meal(
id: '1001',
title: 'Pancakes',
imgUrl: '',
mealTypeFilter: [
MealType.isBreakfast
]
),
Meal(
id: '1002',
title: 'Chicken Wings',
imgUrl: '',
mealTypeFilter: [
MealType.isLunch
]
),
Meal(
id: '1003',
title: 'Yogurt',
imgUrl: '',
mealTypeFilter: [
MealType.isLowCalorie,
MealType.isBreakfast,
MealType.isVegan
]
)
];
我会在 Set 中收集应用的过滤器以避免重复,并过滤餐食 mealTypeFilter 集合是否包含任何应用的过滤器:
Set<MealType> appliedFilters = {};
List<Meal> filteredList = [];
List<Meal> getFilteredList() {
if (appliedFilters.isEmpty) {
return meals;
}
return meals.where((m) => m.mealTypeFilter!.any((f) => appliedFilters.contains(f))).toList();
}
当我触发包含要应用的过滤器的按钮并填充 时,每次在构建方法中我都会调用 getFilteredList() 方法filteredList 我用它来渲染 ListView 结果:
@override
Widget build(BuildContext context) {
filteredList = getFilteredList();
// rest of the code here
}
请参阅 Gist 了解完整代码,并通过 DartPad 运行 查看它的实际效果,如下所示:
希望这能奏效。