我在我的购物 list 应用程序中使用Riverpod进行状态管理.对于产品屏幕,我想添加一个实时搜索栏,以便用户可以过滤某些产品.

我使用SQFlite作为数据库,并使用Repository模式来访问它. 以下是我到目前为止设法编写的代码,但它在搜索栏中没有返回任何内容.

final productProvider = FutureProvider<Map<String, dynamic>?>((ref) async {
  final searchText = ref.watch(searchTextProvider);
  final repository = Repository<Product>("Product");

  if (searchText.isNotEmpty) {
    final result = await repository.getByName(searchText);
    return result;
  }
  return null;
});

final searchTextProvider = StateProvider<String>((ref) => '');

class ProductScreen extends ConsumerWidget {
  const ProductScreen({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final productsAsyncValue = ref.watch(productProvider);

    return Scaffold(
      appBar: AppBar(
        title: const Text('Tela de Produtos'),
      ),
      body: Column(
        children: [
          TextField(
            onChanged: (value) {
               ref.read(searchTextProvider);
            },
            decoration: const InputDecoration(
              labelText: 'Pesquisar',
            ),
          ),
          Expanded(
            child: productsAsyncValue.when(
              data: (data) {
                if (data != null) {
                  return ListView.builder(
                    itemCount: data.length,
                    itemBuilder: (context, index) {
                      final product = data[index];
                      return ListTile(
                        title: Text(product['name']),
                      );
                    },
                  );
                } else {
                  return Text('Nenhum resultado encontrado');
                }
              },
              loading: () => CircularProgressIndicator(),
              error: (error, stackTrace) => Text('Erro: $error'),
            ),
          ),
        ],
      ),
    );
  }
}

以下是My Repository中getByName的代码,如果这是问题所在:

Future<Map<String, dynamic>?> getByName(String name) async {
    final map = await dbProvider.db.query(
      tableName,
      where: 'name = ?',
      whereArgs: [name],
    );
    if (map.isNotEmpty) {
      return map.first;
    }
    return null;
  }

推荐答案

这应该可以很好地工作,只需更改以下代码:

onChanged: (value) {
  ref.read(searchTextProvider.notifier).update((_) => value);
},

此外,可能需要返回一些自定义状态,这可以使用sealed个类或老的freezed来实现.您可以定义加载状态、数据、空数据、错误等具体情况,以便在Widget中进行处理.(即使它仍然很好)

Flutter相关问答推荐

想更新ListView上的索引点击块Flutter

Flutter 块消费者仅对特定的状态属性更改做出react

SingleChildScrollView在ErrorWidget.builder中不工作

在Flutter 中创建自定义形状

在Dart中使用Riverpod代码生成时出现问题(addListener)

dotenv:未处理的异常:FileNotFoundError的实例

如何从列表中更新provider变量:Flutter列表和Provider优化指南

Flutter:如何在现有布局之上显示圆角布局?

来自服务器的数据未分配给变量

Flutter Firebase 升级后出现问题? ARC 语义问题 (Xcode): Select 器appleCredentialWithIDToken:rawNonce:fullName:没有已知的类方法

Paypal 支付网关添加带有 magento 2 网络详细信息用户名、密码、签名 Magento 2 的 flutter 应用程序?

为什么 appBar 小部件在 flutter 中不是常量

Show Snackbar above to showModalBottomSheet Flutter

如何在 flutter 中制作这种类型的扩展瓦片

如何在Flutter 中水平滚动堆叠定位的小部件?

在另一个页面编辑数据后更新 Flutter 页面的惯用方法?

我们什么时候在flutter中初始化一个provider?

Textfield 和 MasonryGrid 给出错误(垂直视口的高度没有限制)

如何在 ElevatedButton 上设置背景 colored颜色 动画?

从 Uint8List 或图像对象创建 InputImageData 用于 Google ML Kit 人脸检测