首页 > 解决方案 > 如何在我的 Flutter 中实现 Provider

问题描述

所以每当我尝试调用我的 AnnouncementScreen 页面时,我都会遇到这个错误:

在构建 AnnouncementScreen(dirty, dependencies: [_InheritedProviderScope]) 时抛出了以下断言:尝试使用具有 Listenable/Stream 子类型的 Provider(公告)。

这可能是一个错误,因为更新公告时提供者不会自动更新家属。相反,请考虑将 Provider 更改为处理更新机制的更具体的实现,例如:

或者,如果您正在制作自己的提供程序,请考虑使用 InheritedProvider。

如果您认为这不是错误,您可以通过null在主文件中设置 Provider.debugCheckInvalidValueType 来禁用此检查:

void main() {
  Provider.debugCheckInvalidValueType = null;

  runApp(MyApp());
}

所以我有这个 Provider 叫 Announcements:

import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

import '../models/announcement_model.dart';

class Announcements with ChangeNotifier {
  List _items = [];
  String? token;

  Announcements(this.token, this._items);

  List get items {
    return [..._items];
  }

  Future<void> fetchAnnouncements() async {
    String url = "https://api-staging.xxx/announcements";
    try {
      final response = await http.get(
        Uri.parse(url),
        headers: {HttpHeaders.authorizationHeader: token!},
      );
      final extractedData = json.decode(response.body);
      final List loadedProducts = [];
      extractedData.forEach((prodId, data) {
        loadedProducts.add(
            Announcement(id: prodId, title: data['title'], body: data['body']));
      });
      _items = loadedProducts;
      notifyListeners();
    } catch (e) {
      throw (e);
    }
  }
}

所以我有一个announcement_screen 基本上将所有项目数据从公告中提取到一个列表中。

这是我的 main.dart 文件(它返回这个 MultiProvider):

MultiProvider(
      providers: [
        ChangeNotifierProvider.value(
          value: Auth(),
        ),
        ProxyProvider<Auth, Announcements>(
          update: (_, auth, previousProducts) => Announcements(
            auth.token,
            previousProducts == null ? [] : previousProducts.items,
          ),
        ),
      ],
      child: Consumer<Auth>(
        builder: (ctx, auth, _) => MaterialApp(
          title: 'XXX',
          theme: ThemeData(),
          home: NavigationScreen(),
        ),
      ),
    );

这就是我在announcement_screen.dart 中使用Provider 的方式(只关注Provider 的使用):

class AnnouncementScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final announcementData = Provider.of<Announcements>(context);
    return Scaffold(
      backgroundColor: Color(0xff1e1e1e),
      body: SafeArea(
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Column(
            children: [
              SizedBox(
                height: 90,
              ),
              Text(
                'Good Morning, John',
                style: TextStyle(
                  fontSize: 32,
                  fontFamily: 'Casper',
                  color: Color.fromRGBO(247, 245, 232, 1),
                ),
              ),
              SizedBox(
                height: 10,
              ),
              Expanded(
                child: SizedBox(
                  height: 200.0,
                  child: FutureBuilder(
                    future: Provider.of<Announcements>(context)
                        .fetchAnnouncements(),
                    builder: (ctx, snapshot) => snapshot.connectionState ==
                            ConnectionState.waiting
                        ? Center(child: CircularProgressIndicator())
                        : ListView.builder(
                            itemCount: announcementData.items.length,
                            itemBuilder: (context, index) {
                              return Column(
                                children: [
                                  _tile(announcementData.items[index].title,
                                      announcementData.items[index].body),
                                  Divider(
                                    thickness: 4,
                                    indent: 0,
                                    endIndent:
                                        MediaQuery.of(context).size.width / 1.4,
                                    color: Color.fromRGBO(198, 158, 96, 1),
                                  ),
                                ],
                              );
                            }),
                  ),
                ),
              ),
              DiamondButton(),
              SizedBox(
                height: 20,
              )
            ],
          ),
        ),
      ),
    );
  }
}

标签: flutterdartprovider

解决方案


推荐阅读