嗨所有我试图创建一个搜索栏,但我不能我很新,我有一个列表在CartModel类,我显示在一个FruitsPage类,但我不能过滤搜索结果。
CartModel
class CartModel extends ChangeNotifier {
final List _shopItems = const [
// [ itemName, itemPrice, imagePath, color ]
["Avocado", "4", "assets/images/8c.png", Colors.green],
["Banana", "2", "assets/images/8c.png", Colors.yellow],
["pollo", "12", "assets/images/8c.png", Colors.brown],
["acqua", "1", "assets/images/8c.png", Colors.blue],
["mela", "3", "assets/images/8c.png", Colors.red],
["broccoli", "3", "assets/images/8c.png", Colors.brown],
];
get shopItems => _shopItems;
食品杂货项目瓷砖
class GroceryItemTile extends StatelessWidget {
final String itemName;
final int itemPrice;
final String imagePath;
// ignore: prefer_typing_uninitialized_variables
final color;
void Function()? onPressed;
GroceryItemTile({
super.key,
required this.itemName,
required this.itemPrice,
required this.imagePath,
required this.color,
required this.onPressed,
});
FruitsPage
class FruitsPage extends StatefulWidget {
const FruitsPage({super.key});
@override
State<FruitsPage> createState() => _FruitsPageState();
}
class _FruitsPageState extends State<FruitsPage> {
String _searchText = '';
List _filteredShopItems = [];
@override
void initState() {
super.initState();
_filteredShopItems = cartmode.shopItems;
}
void _filterShopItems(String query) {
setState(() {
_searchText = query;
_filteredShopItems = cartmode.shopItems
.where((item) => item[0].toLowerCase().contains(query.toLowerCase()))
.toList();
});
}
CartModel cartmode = CartModel();
@override
@override
Widget build(BuildContext context) {
Device.screenType == ScreenType.tablet;
return Container(
margin: EdgeInsets.only(top: 20),
width: 100.w,
height: 100.5.h,
child: Container(
width: 100.w,
height: 20.5.h,
child: Consumer<CartModel>(builder: (context, value, child) {
return Scaffold(
appBar: AppBar(
title: CupertinoSearchTextField(
autocorrect: true,
onSubmitted: (value) {
_filterShopItems(value);
},
),
backgroundColor: Colors.white,
elevation: 0,
iconTheme: IconThemeData(
color: Colors.grey[800],
)),
body: GridView.builder(
padding: const EdgeInsets.all(12),
//physics: const NeverScrollableScrollPhysics(),
itemCount: value.shopItems.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: 1 / 1.2,
),
itemBuilder: (context, index) {
return GroceryItemTile(
itemName: value.shopItems[index][0].toString(),
itemPrice: int.parse(
value.shopItems[index][1].toString()),
imagePath: (value.shopItems[index][2]),
color: value.shopItems[index][3],
onPressed: () =>
Provider.of<CartModel>(context, listen: false)
.addItemToCart(index),
);
},
),
);
})));
}
}
如果有人能给我一些建议,我会很高兴,我不明白为什么搜索不给我结果,它还在控制台打印一个错误,即'The following_TypeError was thrown while calling onSubmitted for www.example.com:type'(dynamic)=〉dynamic 'is not a subtype of type'(dynamic)=〉bool 'of' test''TextInputAction.search: type '(dynamic) => dynamic' is not a subtype of type '(dynamic) => bool' of 'test'**'
1条答案
按热度按时间mlmc2os51#
你的_filterShopItems()函数按预期工作。问题是,你在代码中混合了2个状态管理。让我解释一下......我在你的代码中看到你使用了StatefulWidget和Provider。
所以你的代码是这样运行的。(),the _filterShopItems()函数运行,这将调用setState()和_filteredShopItems将根据您的查询进行更改。(),FruitsPage重建。接下来,参见GridView.builder中的itemBuilder()。它使用
value
构建购物项目。这个value
是来自Provider的CartModel,它是您未过滤的购物列表(_filterShopItems不会更改CartModel Provider中的状态。只有widget中的_filteredShopItems)。因此,widget显示未过滤的购物列表。要解决这个问题,你有两个选择。要么在StatefulWiget中管理状态,要么使用Provider。
1.使用StatefulWidget
在itemBuilder中,将
value.shopItems
更改为_filteredShopItems
。示例:value.shopItems[index][1] -〉_filteredShopItems[index][1]1.使用提供程序(可能难以理解)
应该更改_filterShopItems()中的逻辑。您应该更改
CartModel.shopItems而不是_filteredShopItems。由于Provider负责状态管理,因此您不需要调用setState()。此外,_filteredShopItems没有使用,因此您可以删除一些变量,并且FruitsPage不再需要statefulWidget...
希望有帮助!请随时提出其他问题
编辑:
我没看到你还有别的问题
要解决这个问题,很简单。
这个错误发生是因为
.where
只能出现在List类型之后。如果你没有指定,get方法返回一个动态的。编辑2:
样本代码: