[英]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.