flutter riverpod ConsumerWidget не восстанавливается

Я только что реализовал Riverpod в своем небольшом приложении.

flutter_riverpod: ^ 0.12.1

Моя проблема в том, что когда я обновляю провайдера, виджет не перестраивается, несмотря на то, что я сделал вызов «смотреть».

По сути, провайдер отслеживает текущую страницу, которая должна отображаться.

import 'dart:developer';

import 'package:flutter_riverpod/flutter_riverpod.dart';

final currentPageProvider = StateNotifierProvider((ref) => CurrentPage());

class CurrentPage extends StateNotifier<int> {
  CurrentPage() : super(-1);

  set currentPage(int page) {
    log('currentPage set to $page');
    state = page;
  }

  int get currentPage => state;
}

Виджет PageButtons рисует набор RaisedButtons. Когда пользователь нажимает одну из поднятых кнопок, номер текущей страницы. должен измениться, а виджет PageButton должен быть перестроен, чтобы мы могли изменить цвет RaisedButton, соответствующий текущей странице.

import 'dart:developer';
import 'dart:math' hide log;

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:fsm2/fsm2.dart' hide State;
import 'package:fsm2_viewer/src/providers/current_page.dart';
import 'package:fsm2_viewer/src/providers/log_provider.dart';

class PageButtons extends ConsumerWidget {
  final List<SvgFile> pages;
  PageButtons(this.pages);

  @override
  Widget build(BuildContext context, ScopedReader watch) {
    /// watch the currentPageProvider so we are rebuilt when the page
    /// no changes.
    int currentPage = watch(currentPageProvider).currentPage;
    log('building PageButons currentPage: $currentPage');
    if (pages.length == 0) {
      return Container(width: 0, height: 0);
    }

    currentPage = min(currentPage, pages.length - 1);

    var buttons = <Widget>[];
    for (var pageNo = 0; pageNo < pages.length; pageNo++) {
      buttons.add(Padding(
          padding: EdgeInsets.only(right: 5, left: 5),
          child: RaisedButton(
              color: (pageNo == currentPage ? Colors.blue : Colors.grey),
              onPressed: () {
                context.read(logProvider).log = 'onpressed';
                /// User click the page button so update the current page.
                context.read(currentPageProvider).currentPage = pageNo;
                context.read(logProvider).log = 'changed to page $pageNo';
              },
              child: Text('${pageNo + 1}'))));
    }
    return Row(children: buttons);
  }
}

Вы можете увидеть в приведенном выше методе сборки, который я называю watch:

 int currentPage = watch(currentPageProvider).currentPage;

Затем в onPressed для кнопки Raised я обновляю currentPage:

              onPressed: () {
                /// User click the page button so update the current page.
                context.read(currentPageProvider).currentPage = pageNo;
                context.read(logProvider).log = 'onpressed';                
                context.read(logProvider).log = 'changed to page $pageNo';

В своих логах я вижу:

main:ALL> onpressed
main:ALL> currentPage set to 1
main:ALL> changed to page 1

Журналы сообщают мне, что вызывается метод onPressed и что я обновляю currentPageProvider.

Однако построитель PageButtons не вызывается.

Что я делаю неправильно?


person Brett Sutton    schedule 17.12.2020    source источник
comment
Установлено значение 1. Что было до этой строки? Состояние должно измениться, чтобы получить уведомление.   -  person Randal Schwartz    schedule 17.12.2020
comment
Это всего лишь догадка, но я не уверен, что наблюдение за значением вашего геттера приведет к тому же поведению, что и наблюдение за состоянием напрямую.   -  person Alex Hartford    schedule 17.12.2020
comment
@RandalSchwartz Он отображает несколько кнопок, и я тестировал их изменение на разные значения.   -  person Brett Sutton    schedule 18.12.2020
comment
@AlexHartford Если я изменю строку для использования состояния, я получаю предупреждение: int currentPage = watch (currentPageProvider) .state; Член «состояние» может использоваться только в членах экземпляра подклассов «package: state_notifier / state_notifier.dart».   -  person Brett Sutton    schedule 18.12.2020
comment
@BrettSutton Вместо этого вам нужно сделать следующее: currentPage = watch (currentPageProvider.state);   -  person Alex Hartford    schedule 18.12.2020
comment
Как однажды сказал Гомер: Да. спасибо, что исправили.   -  person Brett Sutton    schedule 18.12.2020


Ответы (1)


person    schedule
comment
Пожалуйста, не публикуйте только код в качестве ответа, но также объясните, что делает ваш код и как он решает проблему вопроса. Ответы с объяснением обычно более полезны и качественнее, и с большей вероятностью получат положительные отзывы. - person Ran Marciano; 01.03.2021
comment
он просто пропустил ключевое слово состояния int currentPage = watch (currentPageProvider.state); // теперь вы следите за состоянием stateNotifierProvider, а не за самим провайдером - person Daniel Aidoo; 01.03.2021