dart flutter

dart - Error: solo se puede acceder a los miembros estáticos en los inicializadores, ¿qué significa esto?



flutter (3)

Tengo algo como esto. Estoy teniendo dificultades para entender este error. ¿Por qué el acceso a filterController aquí da este error aquí? ¿Pero no da este error si muevo la creación completa de TextFormField actual (entre los comentarios A y B) dentro del método de compilación? ¿Cómo mover el TextFormField completo dentro del método de compilación hace que filterController y resuelva este problema?

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

Cómo puedo resolver este problema ?


Además, puedes mantener eso como método:

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

y usarlo en la interfaz de usuario:

body: Container( child: getEmailController(); )


Puede convertir esta variable en una función y puede tomar contexto en los parámetros de esta función.

Ejemplo

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

Pero, creo que quieres mostrar un mensaje de error. Entonces, puedes hacerlo con un diálogo no con una página. Es más eficiente porque puede especificar su cuadro de diálogo con botones o mensajes y puede usar este diálogo de error en cualquier lugar. Miremos mi función de ayuda global para mostrar mensajes de error.

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


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

... es un inicializador y no hay forma de acceder a this en este momento. Los inicializadores se ejecutan antes que el constructor, pero solo se puede acceder a ellos después de que se completó la llamada al super constructor (implícito en su ejemplo). Por lo tanto, solo en el cuerpo del constructor (o posterior) se permite el acceso a this .

Es por esto que recibes el mensaje de error:

controller: filterController,

accede a this.filterController ( this es implícito si no lo escribes explícitamente).

Para solucionar su problema (suponiendo que el email debe ser final ) puede usar un constructor de fábrica y una lista de inicializadores de constructor:

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;

o cuando el campo de email no necesita ser final, el email se puede inicializar en la lista de inicializadores del constructor:

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;

pero en los widgets Flutter, initState se usa generalmente para eso

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;