【问题标题】:Error: Only static members can be accessed in initializers what does this mean?错误:在初始化程序中只能访问静态成员这是什么意思?
【发布时间】:2018-10-13 04:24:33
【问题描述】:

我有这样的东西。我很难理解这个错误。 为什么在此处访问filterController 会出现此错误,但如果我将当前整个TextFormField 创建(在cmets A 和B 之间)移动到build 方法中,它不会出现此错误?那么如何在 build 方法中移动整个 TextFormField 使 filterController 静态并解决此问题?

class AppHomeState extends State<AppHome> with SingleTickerProviderStateMixin
{

    TabController _tabController;
    final filterController = new TextEditingController(text: "Search");
        //----A
        TextFormField email = new TextFormField(
        keyboardType: TextInputType.emailAddress,
        controller: filterController,    ------>ERROR : Error: Only static members can be accessed in initializers
        );
       //----B

  @override
    Widget build(BuildContext context)
    {
        return new Scaffold(
                appBar: new AppBar(..),
        );
    }
}

我该如何解决这个问题?

【问题讨论】:

  • 我认为我们需要更多的上下文(哈哈)才能正确回答这个问题。重要的部分是你在哪里定义了这段代码。根据您描述的错误(Error : Only static members can be accessed in initializers),它位于类的构造函数中。在颤振中,您实际上不应该在构造函数中构建任何东西。因此,如果您可以发布整个课程,那肯定会帮助我们帮助您!
  • 很高兴他的回答有所帮助,但我认为这不是一个特别正确的答案,因为它没有解决问题的原因或引导您避免再次出现问题。如果您只是通过调用函数替换变量,我希望您会得到相同的错误。如果他编辑建议你然后调用他在构建函数中定义的函数,而不是你可能正在做的构造函数中定义的函数,那么我会认为这是一个更正确的答案......
  • 我马上试试这个
  • @rmtmckenzie 在经历了这个之后看起来这不是我想要的,因为它不能解决问题。
  • 好的。请编辑您的问题以包括您的整个班级。那么我或其他人将能够更好地帮助您。

标签: dart flutter


【解决方案1】:

你可以这样做:首先声明并在你的 didChangeDependencies() 方法中初始化之后,像这样

声明你的变量

List<Tab> tabsList = [];

初始化tabsList

 tabsList = [
    Tab(text: getTranslated(context, "tab_1")),
    Tab(text: getTranslated(context, "tab_2")),
    Tab(text: getTranslated(context, "tab_3"))
 ];

完整代码示例

class _MyClassState extends State<MyClass>
    with TickerProviderStateMixin<MyClass> {

  TabController tabController;
  List<Tab> tabsList = [];

  @override
  void didChangeDependencies() {
    tabsList = [
      Tab(text: getTranslated(context, "tab_1")),
      Tab(text: getTranslated(context, "tab_2")),
      Tab(text: getTranslated(context, "tab_3"))
    ];
    tabController =
        TabController(length: tabsList.length, vsync: this, initialIndex: 0);

    super.didChangeDependencies();
  }
}

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,我可以通过将我需要的值添加到控制器的文本中来设置 TextFormField 的初始值来解决这个问题,例如:

    _carPlateController.text = _initValues['carPlate'];
    

    filterController.text = 'search';
    

    我希望这会有所帮助!因为它在使用控制器时是一种优雅而简单的解决方案。

    【讨论】:

      【解决方案3】:

      你可以把它作为一种方法:

      Widget getEmailController(){
      return new TextFormField(
              keyboardType: TextInputType.emailAddress,
              controller: filterController,
              );
      }
      

      并在 UI 中使用它:

      body: Container(
      child: getEmailController();
      )
      

      【讨论】:

        【解决方案4】:
        class AppHomeState extends State<AppHome> with SingleTickerProviderStateMixin {
        
            TabController _tabController;
            final filterController = new TextEditingController(text: "Search");
            TextFormField email = ...
        

        ... 是一个初始化器,此时无法访问this。 初始化程序在构造函数之前执行,但 this 仅允许在调用超级构造函数(在您的示例中隐含)完成后访问。 因此,仅允许在构造函数主体(或更高版本)中访问this

        这就是您收到错误消息的原因:

        controller: filterController,
        

        访问this.filterControllerthis 是隐含的,如果你不写明确的话)。

        要解决您的问题(假设 email 需要为 final),您可以使用工厂构造函数和构造函数初始化程序列表:

        class AppHomeState extends State<AppHome> with SingleTickerProviderStateMixin {
          factory SingleTickerProviderStateMixin() => 
              new SingleTickerProviderStateMixin._(new TextEditingController(text: "Search"));
        
          SingleTickerProviderStateMixin._(TextEditingController textEditingController) : 
              this.filterController = textEditingController,   
              this.email = new TextFormField(
                keyboardType: TextInputType.emailAddress,
                controller: textEditingController);
        
          TabController _tabController;
          final filterController;
          final TextFormField email;
        

        或者当email字段不需要是final时email可以在构造函数初始化列表中初始化:

        class AppHomeState extends State<AppHome> with SingleTickerProviderStateMixin {
        
          SingleTickerProviderStateMixin() {
            email = new TextFormField(
                keyboardType: TextInputType.emailAddress,
                controller: filterController,
            );
          }
        
          TabController _tabController;
          final filterController = new TextEditingController(text: "Search");
          TextFormField email;
        

        但在 Flutter 小部件中,initState 通常用于此目的

        class AppHomeState extends State<AppHome> with SingleTickerProviderStateMixin {
        
          @override
          void initState() {
            super.initState();
            email = new TextFormField(
                keyboardType: TextInputType.emailAddress,
                controller: filterController,
            );
          }
        
          TabController _tabController;
          final filterController = new TextEditingController(text: "Search");
          TextFormField email; 
        

        【讨论】:

        • 感谢您现在解释这一点,这绝对是有道理的。
        【解决方案5】:

        您可以将此变量转换为函数,并且可以在此函数参数中获取上下文。

        例子

        Widget myDialog (BuildContext context) {
          return new Scaffold(
            backgroundColor: Colors.white,
            body: new Center(
              child: new Column(
                children: <Widget>[
                  new Text("Invalid Username/Password"),
                  new Text("Please verify your login credentials"),
                  new RaisedButton(
                    child: new Text("Ok"),
                    onPressed:() {
                      Navigator.pop(context);//Error : Only static members can be accessed in initializers
                    }
                  ),
                ],
              ),
            )
          );
        }
        
        // Using if you are doing in a class
        this.myDialog(context);
        
        // Using if you are using a global function
        myDialog(context);
        

        但是,我认为您想显示一条错误消息。因此,您可以使用对话框而不是页面来完成。它更有效,因为您可以使用按钮或消息指定对话框,并且可以在任何地方使用此错误对话框。让我们看看我用于显示错误消息的全局帮助函数。

        void showError(BuildContext context, String error) {
          showSnackBar(
            context,
            new Text(
              'Error',
              style: new TextStyle(color: Theme.of(context).errorColor),
            ),
            content: new SingleChildScrollView(
              child: new Text(error)
            ),
            actions: <Widget>[
              new FlatButton(
                child: new Text(
                  'Ok',
                  style: new TextStyle(
                    color: Colors.white
                  ),
                ),
                onPressed: () {
                  Navigator.of(context).pop();
                },
                color: Theme.of(context).errorColor,
              ),
            ]
          );
        }
        
        // Using in everywhere
        showError(context, 'Sample Error');
        

        【讨论】:

        • @Anilcan 我认为这不会帮助解决他的问题的根本原因(这可能是他在他的类的构造函数而不是构建函数中这样做)。它可能会切题地解决它,因为尽管他以这种方式重写了他的课程,但最好提及一下。
        • btw 在您推荐的代码中showSnackBar 定义在哪里?
        猜你喜欢
        • 2020-08-31
        • 2020-02-09
        • 1970-01-01
        • 1970-01-01
        • 2020-01-05
        • 2020-01-03
        • 2020-10-26
        • 2019-01-23
        相关资源
        最近更新 更多