错误:在初始化程序中只能访问静态成员,这是什么意思?

时间:2018-05-03 00:02:27

标签: dart flutter

我有类似的东西。我很难理解这个错误。 为什么在这里访问filterController会出现此错误?但是如果我在构建方法中移动当前的整个TextFormField创建(在注释A和B之间),它不会给出这个错误吗?如何移动构建方法中的整个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(..),
        );
    }
}

如何解决此问题?

5 个答案:

答案 0 :(得分:21)

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; 

答案 1 :(得分:1)

此外,您可以将其保留为一种方法:

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

并在用户界面中使用它:

body: Container(
child: getEmailController();
)

答案 2 :(得分:1)

我遇到了同样的问题,我能够通过在控制器的文本中添加所需的值来设置TextFormField的初始值来解决此问题,例如:

_carPlateController.text = _initValues['carPlate'];

filterController.text = 'search';

我希望这会有所帮助!因为这是使用控制器时的简单易用的解决方案。

答案 3 :(得分:1)

您可以这样操作:首先在didChangeDependencies()方法中声明并初始化,如下所示

声明了变量

az webapp config appsettings set --resource-group <resource-group-name> --name <app-name> --settings WEBSITES_PORT=5000

已初始化List<Tab> tabsList = [];

tabsList

完整代码示例

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

答案 4 :(得分:0)

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

实施例

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');