【问题标题】:dependOnInheritedElement() was called before initstate() in flutter在颤振中在 initstate() 之前调用了dependOnInheritedElement()
【发布时间】:2020-06-07 08:38:19
【问题描述】:

我目前在获取 Provider' value ininitstate 时遇到问题。

我想在 Appbar 的下拉列表和正文的其他部分设置默认值。但我收到一条错误消息,提示 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

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 在模型文件夹中

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 在模型文件夹中

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() 的情况下工作(我听说提供者模式不需要stful)

我提出initstate() 的原因是这是唯一的解决方案(据我所知)在提供程序中设置默认值。

希望大家帮帮我!


通过在button_data.dart 中添加 Button_data 构造函数解决了问题。

ButtonData () {
    _selectedButton = _buttons.first;
  }

【问题讨论】:

    标签: flutter dart flutter-provider


    【解决方案1】:

    我在之前的回答中还提到,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 设置默认值。在每种编程语言中,当您声明一个带有值的变量时,该值将成为它的初始/默认值,您可以稍后更改它。

    您可以在ButtonData 类中编辑以下内容,而不是使用initState

    //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! :)
    

    【讨论】:

    • 我在initial value中将listen参数设置为false。返回相同的错误。你可以检查一下,因为我上传了完整的代码。
    • 第二种方式——用button_data.dart中的值声明一个变量。——这就是我最初的意图。但是当我用你所说的值声明一个变量时,错误返回Only static members can be accessed in initializers。我上传了完整的代码,你也可以检查一下。
    • 如果可能,我想修复第二个问题only static member...。但据我所知,这很难解决。这就是为什么我试图以不同的方式绕过它。
    • 问题已解决。我刚刚编辑了我的块。真的感谢您看我的问题。 @BasedMusa
    猜你喜欢
    • 2019-01-16
    • 1970-01-01
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 2021-05-29
    • 2021-06-05
    相关资源
    最近更新 更多