[英]Flutter Riverpod FutureProvider
我尝试使用 riverpod 进行搜索但没有成功,我创建了一个 FutureProvider,当我创建我的 Widget 时,我运行 watch 一个具有默认值的 FutureProvider,因此我需要单击一个按钮并使用另一个值再次执行搜索. 为什么当我单击按钮时 CircularProgressIndicator 不显示的逻辑工作?
谢谢
我的服务
import 'dart:async';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:i_condominio/models/Condominio.dart';
final condominioPRovider = Provider((ref) => CondominioService());
final condFuture =
FutureProvider.autoDispose.family<List<Condominio>, String>((ref, arg) {
final serviceProvider = ref.watch(condominioPRovider);
return serviceProvider.findByCepFuture(arg);
});
class CondominioService {
Future<List<Condominio>> findByCepFuture(String cepProcura) async {
List<Condominio> listCondominio = [
Condominio(
nome: 'Porto panorama',
cep: Cep(
cep: "11075-350",
logradouro: "Rua Monsenhor Paula Rodrigues",
complemento: "",
bairro: "Vila Belmiro",
localidade: "Santos",
uf: "SP",
ibge: "3548500"),
numero: "129"),
Condominio(
nome: 'Central Park',
cep: Cep(
cep: "11075-350",
logradouro: "Rua Monsenhor Paula Rodrigues",
complemento: "",
bairro: "Vila Belmiro",
localidade: "Santos",
uf: "SP",
ibge: "3548500"),
numero: "126"),
Condominio(
nome: 'Sao Vicente park',
cep: Cep(
cep: "11380-120",
logradouro: "Rua Monsenhor Paula Rodrigues",
complemento: "",
bairro: "Vila Belmiro",
localidade: "Santos",
uf: "SP",
ibge: "3548500"),
numero: "130")
];
print('buscando $cepProcura');
await Future.delayed(const Duration(seconds: 1));
final retorno = listCondominio
.where((element) => element.cep.cep == cepProcura)
.toList();
print('acabou ${retorno.length}');
return Future.value(retorno);
}
}
和我的小部件
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:i_condominio/models/Condominio.dart';
import 'package:i_condominio/services/CondominioService.dart';
import 'package:mask_text_input_formatter/mask_text_input_formatter.dart';
class SelecionarCondominioPage extends ConsumerWidget {
const SelecionarCondominioPage({super.key});
selecionarCondoninio(Condominio e) {
print('condominio Selecionado ${e.nome}');
}
@override
Widget build(BuildContext context, WidgetRef ref) {
final cf = ref.watch(condFuture('11380-120'));
var maskFormatter = MaskTextInputFormatter(
mask: '#####-###',
filter: {"#": RegExp(r'[0-9]')},
type: MaskAutoCompletionType.lazy);
return Scaffold(
appBar: AppBar(
title: const Text('Novo usuario'),
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
inputFormatters: [maskFormatter],
decoration: const InputDecoration(
labelText: 'CEP',
),
keyboardType: TextInputType.number,
),
),
const Padding(
padding: EdgeInsets.all(8.0),
child: Text(
"Condominios encontrados",
style: TextStyle(fontSize: 22),
),
),
ElevatedButton(
onPressed: () => ref.watch(condFuture('11075-350')),
child: const Text('Buscar 11075-350'),
),
cf.when(
data: (data) => Expanded(
child: ListView(
children: [
...data.map((e) => ListTile(
title: Text(e.nome),
subtitle: Text(e.enderecoCompleto),
onTap: () => showDialog(
context: context,
builder: ((ctx) => AlertDialog(
title: const Text(
'Condominio selecionado'),
content: Text(
'Confirma o condominio ${e.nome}'),
actions: [
const TextButton(
onPressed: null,
child: Text("OK")),
TextButton(
onPressed: () =>
Navigator.of(context).pop(),
child: const Text("CANCELAR")),
],
)),
)))
],
),
),
error: (error, n) => Text(error.toString()),
loading: () => const Center(child: CircularProgressIndicator())),
],
),
);
}
}
在这种情况下,最好使用StateNotifierProvider
,如文档中所示
FutureProvider 不提供在用户交互后直接修改计算的方法。 它旨在解决简单的用例。 对于更高级的场景,请考虑使用 StateNotifierProvider。
供应商
final condominioNotifierProvider = StateNotifierProvider<CondominioNotifier,
AsyncValue<List<Condominio>>>((ref) {
final service = ref.watch(condominioPRovider);
return CondominioNotifier(service);
});
class CondominioNotifier extends StateNotifier<AsyncValue<List<Condominio>>> {
CondominioNotifier(this.service) : super(const AsyncValue.loading()) {
load('11380-120');
}
final CondominioService service;
Future<void> load(String name) async {
state = AsyncValue.loading();
try {
final data = await service.findByCepFuture(name);
state = AsyncValue.data(data);
} on Exception catch(e) {
state = AsyncValue.error(e, StackTrace.current);
}
}
}
微件
Widget build(BuildContext context, WidgetRef ref) {
final cf = ref.watch(condominioNotifierProvider);
...
ElevatedButton(
onPressed: () => ref.read(condominioNotifierProvider.notifier).load('11075-350'),
child: const Text('Buscar 11075-350'),
),
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.