簡體   English   中英

Flutter Riverpod FutureProvider

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM