提供者和消费者问题

问题描述

我对 Flutter 还很陌生,我正在尝试通过提供程序包来提高我的状态管理技能。我在加载我的类别和通知听众何时显示我的类别小部件而不是我的 modalprogressHUD 时遇到了一些困难

这是 MyApp 类:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<LoginProvider>(
          create: (_) => LoginProvider(),),ChangeNotifierProvider<CatergoryProvider>(
          create: (_) => CatergoryProvider(),ChangeNotifierProvider<RegistrationProvider>(
          create: (_) => RegistrationProvider(),ChangeNotifierProvider<QuestionProvider>(
          create: (_) => QuestionProvider(),],child: MaterialApp(
        title: 'Flutter Demo',debugShowCheckedModeBanner: false,theme: ThemeData.dark().copyWith(
          primaryColor: Colors.teal,initialRoute: DashBoard.id,routes: {
          WelcomeScreen.id: (context) => WelcomeScreen(),DashBoard.id: (context) => DashBoard(),QuizzPage.id: (context) => QuizzPage()
        },);
  }
}

我的 CatergoryProvider 类:

import 'dart:convert';

import 'package:Flutter/cupertino.dart';
import 'package:quizz_app/models/catergory.dart';
import 'package:quizz_app/services/services.dart';

class CatergoryProvider with ChangeNotifier {
  List<Catergory> catergory;
  String errorMessage;
  bool loading = false;

  Future<bool> fetchCatergory() async {
    setLoading(true);

    await Service(url: "https://quizapp1234.herokuapp.com/kategori")
        .fetchCatergory()
        .then((data) {
      if (data.statusCode == 200) {
        print('success');
        Iterable l = json.decode(data.body);
        setCatergory(
            List<Catergory>.from(l.map((data) => Catergory.fromJson(data))));
        setLoading(false);
      } else {
        Map<String,dynamic> result = json.decode(data.body);
        setMessage(result['message']);
      }
    });
    return isList();
  }

  bool isLoading() {
    return loading;
  }

  void setLoading(value) {
    loading = value;
    notifyListeners();
  }

  void setCatergory(value) {
    catergory = value;
    notifyListeners();
  }

  void setMessage(value) {
    errorMessage = value;
    notifyListeners();
  }

  List<Catergory> getList() {
    return catergory;
  }

  String getMessage() {
    return errorMessage;
  }

  bool isList() {
    return catergory != null ? true : false;
  }
}

这里是我包装我想要通知消费者的地方:

  Consumer<CatergoryProvider>(
    builder: (context,catergory,child) {
      catergory.fetchCatergory();
      catergories = catergory.getList();
      return catergory.isLoading()
          ? ModalProgressHUD(
              opacity: 0,inAsyncCall:
                  Provider.of<CatergoryProvider>(context).isLoading(),child: Scaffold())
          : catergoryPage(catergories,context);
    },

我的调试控制台:

════════ Exception caught by foundation library ════════════════════════════════
setState() or markNeedsBuild() called during build.
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by foundation library ════════════════════════════════
setState() or markNeedsBuild() called during build.
════════════════════════════════════════════════════════════════════════════════

发生的异常:

Exception has occurred.
FlutterError (A CatergoryProvider was used after being disposed.
Once you have called dispose() on a CatergoryProvider,it can no longer be used.)

解决方法

builder: 内的消费者上,您调用 fetchCatergory,在 fetchCatergory 内调用 notifyListeners() 的方法调用函数,每次调用 notifyListeners() 时,{ {1}} 被召回,导致无限循环

仅当 builder: 返回 null 且 catergory.fetchCatergory() 为 false 时才尝试包装 getList()

代码:

isLoading()