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;