我目前在获取Provider' value in初始化状态时遇到问题。
Provider' value in
我想在Appbar和正文的其他部分的下拉列表中设置默认值。但是我说错了dependOnInheritedElement() was called before initstate() in flutter。
dependOnInheritedElement() was called before initstate() in flutter
我的完整代码如下
main.dart
import 'package:test_eoil/model/button_data.dart'; import 'package:test_eoil/model/output_data.dart'; import 'screen/screen.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MultiProvider(providers: [ // ChangeNotifierProvider<ChordData>(create: (context) => ChordData()), ChangeNotifierProvider<OutputData>(create: (context) => OutputData()), ChangeNotifierProvider<ButtonData>(create: (context) => ButtonData()) ], child: MaterialApp( home: Screen(), ), ); } }
screen.dart 在屏幕文件夹中
screen.dart
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_eoil/model/button_data.dart'; import 'package:test_eoil/model/output_data.dart'; class Screen extends StatefulWidget { @override _ScreenState createState() => _ScreenState(); } class _ScreenState extends State<Screen> { Widget dropdownWidget() { return DropdownButton<Button>( items: Provider.of<ButtonData>(context).buttons.map((Button value) { return new DropdownMenuItem<Button>( value: value, child: new Text(value.type.toString()), ); }).toList(), onChanged: (Button newValue) { Provider.of<ButtonData>(context).setSelectedItem(newValue); }, value: Provider.of<ButtonData>(context).selectedButton, ); } @override void initState() { Provider.of<ButtonData>(context).selectedButton = Provider.of<ButtonData>(context).buttons.first; super.initState(); } @override Widget build(BuildContext context) { return Consumer<OutputData>( builder: (context, outputData, child) => Scaffold( appBar: AppBar( title: Text("${Provider.of<ButtonData>(context).selectedButton}"), // new Text(widget.title), // "${Provider.of<ButtonData>(context).selectedButton.key}" actions: <Widget>[ dropdownWidget(), ], ), body: Column( children: <Widget>[ Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ Container( alignment: Alignment.centerRight, padding: new EdgeInsets.symmetric( vertical: 24.0, horizontal: 12.0), child: outputData.outputs[0].output3.length > 2 ? Text( '${outputData.outputs[0].output3.substring(1, outputData.outputs[0].output3.length-1)}', style: TextStyle( fontSize: 35.0, fontWeight: FontWeight.bold, )) : Text('${outputData.outputs[0].output3}', style: TextStyle( fontSize: 35.0, fontWeight: FontWeight.bold, )), ), Container( alignment: Alignment.centerRight, padding: new EdgeInsets.symmetric( vertical: 24.0, horizontal: 12.0), child: outputData.outputs[0].output2.length > 2 ? Text( '${outputData.outputs[0].output2.substring(1, outputData.outputs[0].output2.length-1)}', style: TextStyle( fontSize: 35.0, fontWeight: FontWeight.bold, )) : Text('${outputData.outputs[0].output2}', style: TextStyle( fontSize: 35.0, fontWeight: FontWeight.bold, )), ), Container( alignment: Alignment.centerRight, padding: new EdgeInsets.symmetric( vertical: 24.0, horizontal: 12.0), child: Text('${outputData.outputs[0].output1}', // outputData.outputs[0].output1 style: TextStyle( fontSize: 35.0, fontWeight: FontWeight.bold, )), ), ], ), Expanded( child: new Divider(), ), Column(children: [ Row(children: [ buildButton("CLEAR"), buildButton(""), buildButton("PLAY"), // buildButton("/") ]), ]) ], ))); } Widget buildButton(String buttonText) { return new Expanded( child: new OutlineButton( padding: new EdgeInsets.all(30.0), child: new Text( buttonText, style: TextStyle(fontSize: 20.0), ), onPressed: () => print("test"), ), ); } }
button_data.dart 在模型文件夹中
button_data.dart
import 'package:flutter/foundation.dart'; //import 'dart:collection'; class Button { final int id; final String type; final String numberone; final String numbertwo; final String numberthree; Button({this.id, this.type, this.numberone, this.numbertwo, this.numberthree}); } class ButtonData extends ChangeNotifier { List<Button> _buttons = [ Button( type: "A", numberone: "1", numbertwo: "2", numberthree: "3", ), Button( type: "B", numberone: "A", numbertwo: "B", numberthree: "C", ), ]; List<Button> get buttons => _buttons; Button _selectedButton; Button get selectedButton => _selectedButton; set selectedButton(Button button) { _selectedButton = button; notifyListeners(); } void setSelectedItem(Button s) { _selectedButton = s; notifyListeners(); } Button getKey(String value) { return _buttons .where((button) => button.type == value).first; } String getNumberOne(String value) { return _buttons .where((button) => button.type == value) .map((button) => (button.numberone)) .toString(); } String getNumberTwo(String value) { return _buttons .where((button) => button.type == value) .map((button) => (button.numbertwo)) .toString(); } String getNumberThree(String value) { return _buttons .where((button) => button.type == value) .map((button) => (button.numberthree)) .toString(); } }
output_data.dart 在模型文件夹中
output_data.dart
import 'package:flutter/foundation.dart'; class Output { final int id; String output1; String output2; String output3; Output({this.id, this.output1, this.output2, this.output3}); } class OutputData extends ChangeNotifier { List<Output> _outputs = [ Output(output1: 'Hello', output2: 'Hi', output3: 'Nice'), Output(output1: 'Haha', output2: 'Bye', output3: 'Sad'), ]; List<Output> get outputs { return _outputs; } }
老实说,我想让它initstate()尽可能地工作(我听说提供程序模式不需要稳定)
initstate()
我想出一个的原因initstate()是这是唯一在提供程序中设置默认值的解决方案(据我所知)。
希望你们帮助我!
通过在中添加Button_data构造函数可以解决此问题button_data.dart。
ButtonData () { _selectedButton = _buttons.first; }
我在上一个答案中也提到过,Provider.of(context)它应该在小部件树中使用,而build()方法之外的任何东西都不在小部件树中。但是,如果仍然要使用它,则需要将listen参数设置为false。
Provider.of(context)
build()
listen
false
像这样:
@override void initState() { Provider.of<ButtonData>(context, listen: false).selectedButton = Provider.of<ButtonData>(context, listen: false).buttons.first; super.initState(); }
但是,正如您在问题中提到的那样,您不想使用initState设置默认值。在每种编程语言中,当您声明带有值的变量时,该值将成为其初始值/默认值,以后可以进行更改。
initState
initState您可以在ButtonData课堂上编辑以下内容,而不是使用。
ButtonData
//Remove this. List<Button> get buttons => _buttons; Button _selectedButton; Button get selectedButton => _selectedButton; //Instead, Use this. List<Button> get buttons => _buttons; Button _selectedButton = _buttons.first; Button get selectedButton => _selectedButton; //This will declare the `selectedButton` variable with a default value. //Happy coding! :)