【问题标题】:Consumer not rebuilding UI using riverpod ChangeNotifier消费者不使用 Riverpod ChangeNotifier 重建 UI
【发布时间】:2021-05-15 23:46:03
【问题描述】:

我能够将其缩小为 UI 未更新,消费者未随着数据的变化而更新。我怎样才能让它正常工作?

目标是在模型开始和结束日期变量发生变化时重新加载应用栏文本小部件。

我检查了this 类似的帖子,但他正在使用 stateNotifier。这看起来更复杂,我只是想通过一个简单的演示来学习riverpod...

我尝试过的任何方法都没有奏效。我尝试在屏幕文件中创建一个新的全局提供程序,但什么也没做。尝试改变我在消费者中初始化手表的方式,但什么也没有。我已经验证了,似乎我正在按照文档中所说的 here 做所有事情。我不明白为什么这不起作用。感谢任何帮助和指点!

屏幕:

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:intl/intl.dart';
import 'package:linechart/date_range_widget.dart';
import 'package:linechart/linechart.dart';

class LineChartScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Consumer(builder: (context, watch, child) {
            final startDate = watch(dateController);
            final endDate = watch(dateController);

            final formStart = DateFormat.yMMMd().format(startDate.startDate);
            final formEnd = DateFormat.yMMMd().format(endDate.endDate);

            print(context.read(dateController).startDate);
            print(context.read(dateController).endDate);

            return Text('INCOME GRAPH --- $formStart - $formEnd');
          }),
          backgroundColor: Colors.lightBlue,
          actions: [DateRangeWidget()]),
      body: Column(
        children: [
          SafeArea(
            child: Center(
                child: Padding(
              padding: const EdgeInsets.all(10.0),
              child: LineChart(),
            )),
          ),
        ],
      ),
    );
  }
}

小部件

import 'package:flutter/material.dart';
import 'package:date_range_picker/date_range_picker.dart' as DateRangePicker;
import 'package:flutter_riverpod/flutter_riverpod.dart';

final dateController = Provider((ref) => DatePickModel());

class DateRangeWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return IconButton(
        color: Colors.white,
        icon: Icon(Icons.calendar_today),
        onPressed: () async {
          final List<DateTime> picked = await DateRangePicker.showDatePicker(
              context: context,
              initialFirstDate: context.read(dateController).startDate,
              initialLastDate: context.read(dateController).endDate,
              firstDate: DateTime(2015),
              lastDate: DateTime(DateTime.now().year + 2));
          if (picked != null && picked.length == 2) {
            context.read(dateController).setDates(picked.first, picked.last);
          }
        });
  }
}

class DatePickModel extends ChangeNotifier {
  DateTime _startDate = DateTime.now().subtract(Duration(seconds: 7));
  DateTime _endDate = DateTime.now();

  DateTime get startDate => _startDate;
  DateTime get endDate => _endDate;

  void setDates(DateTime startDate, DateTime endDate) {
    _startDate = startDate;
    _endDate = endDate;
    notifyListeners();
  }

  void resetDates() {
    _startDate = DateTime.now().subtract(Duration(seconds: 7));
    _endDate = DateTime.now();
    notifyListeners();
  }
}

编辑:还尝试将小部件放入单独的 ConsumerWidget 中,但不行...

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:linechart/date_range_widget.dart';
import 'package:linechart/linechart.dart';

class LineChartScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: AppBarTitle(),
          backgroundColor: Colors.lightBlue,
          actions: [DateRangeWidget()]),
      body: Column(
        children: [
          SafeArea(
            child: Center(
                child: Padding(
              padding: const EdgeInsets.all(10.0),
              child: LineChart(),
            )),
          ),
        ],
      ),
    );
  }
}

class AppBarTitle extends ConsumerWidget {
  @override
  Widget build(BuildContext context, ScopedReader watch) {
    context.read(dateController).formatDates();
    final formStart = watch(dateController).startFormatted;
    final formEnd = watch(dateController).endFormatted;
    return Text('INCOME GRAPH --- $formStart - $formEnd');
  }
}

【问题讨论】:

    标签: flutter dart consumer riverpod


    【解决方案1】:

    您需要将Provider 的类型更改为ChangeNotifierProvider。

    当调用 notifyListeners 时,常规提供程序不知道更新,因为它不订阅提供的值。

    final dateController = ChangeNotifierProvider((ref) => DatePickModel());
    

    【讨论】:

    • 嘿亚历克斯,当我这样做时,我收到错误:输入'Provider&lt;DatePickModel&gt;' is not a subtype of type 'ChangeNotifierProvider&lt;DatePickModel&gt;' of 'function result' 以及文本显示为红色,因为消费者不工作。我在这里做错了什么吗?认为即使对于新手来说,这个包也应该很简单。
    • 另外我应该提到的是,使用原始代码中的 Provider 版本,这可以工作,即当我热重新加载时,小部件会重建到正确的最后输入日期。所以除了当日期选择器更新值时消费者没有重建之外,其他一切都正常...... ??
    • @RobbB 更新代码后您是否重新启动了应用程序?
    • 我认为这没有必要,但它成功了!我现在收到一个异常The following assertion was thrown while dispatching notifications for DatePickModel: setState() or markNeedsBuild() called during build. 任何想法,我需要创建一个构造函数还是初始化这两个变量?
    • @RobbB 这可能是因为您在构建方法中调用了formatDates。如果您提出一个新问题,我可以帮助您。
    猜你喜欢
    • 2021-04-21
    • 2021-07-21
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 2020-12-02
    • 2021-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多