обработчик события onSaved в виджете TextFormField не работает
Обработчик события onSaved в виджете TextFormField не работает.
onSaved: (String value) {
setState(() {
_strNameUser = value;
});
},
Если я правильно понимаю, String value это текстовое значение, которе появляется в поле ввода. Затем, я могу его присвоить какой либо переменной. Но ничего не происходит. В контроллер все происходит. Первый код без контроллера, он не работает. Второй код с контроллером, который заменяет onSaved. Там код работает. В чем причина, чего я не понимаю?
Первый код без контроллера, он не работает.
main.dart
import 'package:flutter/material.dart';
import 'package:string_validator/string_validator.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Name App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Name Page'),
),
body: MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
//объявление переменных
String _strNameUser;
String _strEmail;
String _str;
bool _a, _b, _c;
//вызывается один раз при инициализации виджета
@override
void initState() {
super.initState();
_strNameUser = '';
_strEmail = '';
_str = '';
}
@override
void dispose() {
super.dispose();
}
void _f1() {
setState(() {
_a = _strNameUser.isNotEmpty;
_b = _strEmail.isNotEmpty;
_c = isEmail(_strEmail);
if(_a && _b && _c) {
_str = 'user name : $_strNameUser\n email: $_strEmail';
} else {
_str = '';
}
});
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Align(
alignment: Alignment(0.0, -0.65),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
height: 50.0,
margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
alignment: Alignment.center,
child: TextFormField(
onSaved: (String value) {
setState(() {
_strNameUser = value;
});
},
cursorColor: Color(0xffF56323),
style: TextStyle(
color: Colors.deepPurple,
fontSize: 22.0,
),
decoration: InputDecoration(
labelText: 'User Name',
prefixIcon: (_a == null || _a) ? Icon(Icons.person, color: Color(0xffF56323)) : Icon(Icons.error, color: Colors.pink),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
borderSide: BorderSide(),
),
),
),
),
Container(
height: 50.0,
margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
alignment: Alignment.center,
child: TextFormField(
onSaved: (String value) {
setState(() {
_strEmail = value;
});
},
keyboardType: TextInputType.emailAddress,
cursorColor: Color(0xffF56323),
style: TextStyle(
color: Colors.deepPurple,
fontSize: 22.0,
),
decoration: InputDecoration(
labelText: 'Email',
prefixIcon: (_b == null || (_b && _c)) ? Icon(Icons.email, color: Color(0xffF56323)) : Icon(Icons.error, color: Colors.pink),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
borderSide: BorderSide()
),
),
),
),
Container(
height: 50.0,
margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
alignment: Alignment.center,
child: Container(
width: double.infinity,
height: 50.0,
child: FlatButton(
onPressed: () {
_f1();
},
color: Color(0xffF56323).withOpacity(0.9),
splashColor: Colors.amberAccent,
child: Text(
'Ok',
style: TextStyle(
color: Colors.white,
fontSize: 22.0,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)
),
),
),
),
],
),
),
Align(
alignment: Alignment(0.0, 0.85),
child: Text(
_str,
style: TextStyle(
color: Colors.pink,
fontSize: 26.0,
),
),
),
],
);
}
}
Второй код с контроллером работает.
main.dart
import 'package:flutter/material.dart';
import 'package:string_validator/string_validator.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Name App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: Text('Name Page'),
),
body: MyHomePage(),
),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
//объявление переменных
TextEditingController _controllerUserName;
TextEditingController _controllerEmail;
String _strNameUser;
String _strEmail;
String _str;
bool _a, _b, _c;
//вызывается один раз при инициализации виджета
@override
void initState() {
super.initState();
_controllerUserName = TextEditingController();
_controllerEmail = TextEditingController();
_strNameUser = '';
_strEmail = '';
_str = '';
}
@override
void dispose() {
super.dispose();
}
void _f1() {
setState(() {
_strNameUser = _controllerUserName.text;
_strEmail = _controllerEmail.text;
_a = _strNameUser.isNotEmpty;
_b = _strEmail.isNotEmpty;
_c = isEmail(_strEmail);
if(_a && _b && _c) {
_str = 'user name : $_strNameUser\n email: $_strEmail';
} else {
_str = '';
}
});
}
@override
Widget build(BuildContext context) {
return Stack(
children: <Widget>[
Align(
alignment: Alignment(0.0, -0.65),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Container(
height: 50.0,
margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
alignment: Alignment.center,
child: TextFormField(
controller: _controllerUserName,
cursorColor: Color(0xffF56323),
style: TextStyle(
color: Colors.deepPurple,
fontSize: 22.0,
),
decoration: InputDecoration(
labelText: 'User Name',
prefixIcon: (_a == null || _a) ? Icon(Icons.person, color: Color(0xffF56323)) : Icon(Icons.error, color: Colors.pink),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
borderSide: BorderSide(),
),
),
),
),
Container(
height: 50.0,
margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
alignment: Alignment.center,
child: TextFormField(
controller: _controllerEmail,
keyboardType: TextInputType.emailAddress,
cursorColor: Color(0xffF56323),
style: TextStyle(
color: Colors.deepPurple,
fontSize: 22.0,
),
decoration: InputDecoration(
labelText: 'Email',
prefixIcon: (_b == null || (_b && _c)) ? Icon(Icons.email, color: Color(0xffF56323)) : Icon(Icons.error, color: Colors.pink),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10.0),
borderSide: BorderSide()
),
),
),
),
Container(
height: 50.0,
margin: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
alignment: Alignment.center,
child: Container(
width: double.infinity,
height: 50.0,
child: FlatButton(
onPressed: () {
_f1();
},
color: Color(0xffF56323).withOpacity(0.9),
splashColor: Colors.amberAccent,
child: Text(
'Ok',
style: TextStyle(
color: Colors.white,
fontSize: 22.0,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)
),
),
),
),
],
),
),
Align(
alignment: Alignment(0.0, 0.85),
child: Text(
_str,
style: TextStyle(
color: Colors.pink,
fontSize: 26.0,
),
),
),
],
);
}
}
Ответы (1 шт):
К сожалению вы не правильно поняли на счет метода onSaved, он нужен для того чтобы вызывать дополнительный код при сохранении, а value это для отправки в дополнительный код.
https://api.flutter.dev/flutter/material/TextFormField-class.html
onSaved: (String value) {
// This optional block of code can be used to run
// code when the user saves the form.
},
Вам нужно вызывать сохранение формы:
Form.of(primaryFocus.context).save();
А на счет контроллера, вы правильно поняли, он как и следует из названия, управляет/контролирует что-то (в данном примере TextFormField)