Flutter搜索栏它无法正常工作

5f0d552i  于 2023-04-22  发布在  Flutter
关注(0)|答案(1)|浏览(127)

嗨所有我试图创建一个搜索栏,但我不能我很新,我有一个列表在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'**'

mlmc2os5

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...
希望有帮助!请随时提出其他问题
编辑:
我没看到你还有别的问题

The following _TypeError was thrown while calling onSubmitted for TextInputAction.search: type '(dynamic) => dynamic' is not a subtype of type '(dynamic) => bool' of 'test'

要解决这个问题,很简单。

get shopItems => _shopItems;
// Change this to
List get shopItems => _shopItems;

这个错误发生是因为.where只能出现在List类型之后。如果你没有指定,get方法返回一个动态的。
编辑2:
样本代码:

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],
  ];
  List get shopItems => _shopItems;
}

class UnnamedWidget extends StatefulWidget {
  const UnnamedWidget({super.key});

  @override
  State<UnnamedWidget> createState() => _UnnamedWidgetState();
}

class _UnnamedWidgetState extends State<UnnamedWidget> {
  List _filteredShopItems = [];
  String _searchText = "";
  CartModel cartmodel = CartModel();

  @override
  void initState() {
    super.initState();

    _filteredShopItems = cartmodel.shopItems;
  }

  void _filterShopItems(String query) {
    setState(() {
      _searchText = query;
      _filteredShopItems = cartmodel.shopItems
          .where((item) => item[0].toLowerCase().contains(query.toLowerCase()))
          .toList();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: [
          CupertinoSearchTextField(
            placeholder: "Search",
            onSubmitted: (String value) {
              _filterShopItems(value);
            },
          ),
          SizedBox(
            height: 400,
            child: GridView.builder(
              itemCount: _filteredShopItems.length,
              gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2,
                childAspectRatio: 1 / 1.2,
                // childAspectRatio: 5,
              ),
              itemBuilder: (context, index) {
                return GroceryItemTile(
                  itemName: _filteredShopItems[index][0].toString(),
                  itemPrice: int.parse(
                      _filteredShopItems[index][1].toString()),
                  imagePath: (_filteredShopItems[index][2]),
                  color: _filteredShopItems[index][3],
                  onPressed: () =>
                      Provider.of<CartModel>(context, listen: false)
                          .addItemToCart(index),
                  // onPressed: () {},
                );
              }
            ),
          ),
        ],
      )
    );
  }
}

class GroceryItemTile extends StatelessWidget {
  final String itemName;
  final int itemPrice;
  final String imagePath;
  final Color color;
  final void Function()? onPressed;

  const GroceryItemTile({
    super.key,
    required this.itemName,
    required this.itemPrice,
    required this.imagePath,
    required this.color,
    required this.onPressed,
  });

  @override
  Widget build(BuildContext context) {
    return ListTile(
      title: Text(itemName),
      trailing: Container(
        width: 10,
        height: 10,
        decoration: BoxDecoration(
          color: color,
          shape: BoxShape.circle,
        ),
      ),
    );
  }
}

相关问题