Поставщик Flutter прослушивает класс, который расширяет ChangeNotifier позже при создании

#flutter #widget #state #flutter-provider

#flutter #виджет #состояние #поставщик flutter

Вопрос:

Я использую пакет поставщика flutter для создания видимого поведения состояния для классов, которые расширяют ChangeNotifier..

У меня есть класс Person, который расширяет StatelessWidget, чтобы я мог создать виджет Person.

Сначала я создаю экземпляр класса Person один раз в методе builder из

 ChangeNotifierProvider<Person>(
    builder: (context) => Person(name: 'Jim', age: 1),
),
 

и в другой раз позже, в глубине дерева виджетов в качестве дочернего элемента, но у этого другого человека, естественно, нет слушателя…

итак, я попытался обернуть своего второго пользователя внутри другого ChangeNotifierProvider в дереве, но затем я получил эту ошибку:

 ======== Exception caught by widgets library =======================================================
The following assertion was thrown building InheritedProvider<Person>(dirty):
A build function returned null.

The offending widget is: InheritedProvider<Person>
Build functions must never return null.
 

Может быть, проблема в том, что у меня есть 2 ChangeNotifierProviders с одинаковым типом (один с именем «Jim» вверху и один в классе уровня 2 с именем «Bob»), и он не знает, что есть что и как обновить их состояние?
Возможно ли создать 2 класса одного и того же типа ChangeNotifierProviders, только с разными именами или около того? Вот полный код:

  import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<Data>(
          builder: (context) => Data(),
        ),
        ChangeNotifierProvider<Person>(
          builder: (context) => Person(name: 'Jim', age: 1),
        ),
      ],
      child: MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: MyText(),
          ),
          body: Level1(),
        ),
      ),
    );
  }
}

class Person extends StatelessWidget with ChangeNotifier {
  String name;
  int age;
  Person({this.name, this.age});

  void increaseAge() {
    print(age);
    this.age  ;
    notifyListeners();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text(
        'My name is $name and my age is: ${age.toString()}',
      ),
    );
  }
}

class Level1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Level2(),
        FlatButton(
          onPressed: () {
            print(Provider.of<Person>(context).age);
            Provider.of<Person>(context).increaseAge();
          },
          child: Text('Increase person age!'),
        ),
        Text(
            'My name is ${Provider.of<Person>(context).name} and my age is ${Provider.of<Person>(context).age}'),
      ],
    );
  }
}

class Level2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        MyTextField(),
        Level3(),
        ChangeNotifierProvider<Person>(
          builder: (context) => Person(
            name: 'Bob',
            age: 33,
          ),
        ),
      ],
    );
  }
}

class Level3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text(Provider.of<Data>(context).data);
  }
}

class MyText extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Text(Provider.of<Data>(context, listen: false).data);
  }
}

class MyTextField extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return TextField(
      onChanged: (newText) {
        Provider.of<Data>(context).changeString(newText);
      },
    );
  }
}

class Data extends ChangeNotifier {
  String data = 'Some data';

  void changeString(String newString) {
    data = newString;
    notifyListeners();
  }
}