#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();
}
}