在按下的屏幕中点击textformfield
时,将再次调用屏幕的构造函数,并且textformfield
会丢失其值。另外,我认为该屏幕上发生的所有更改都会导致再次调用其构造函数,而我根本不知道原因。
以下是生成错误的示例代码:
import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',home: MyHomePage(title: 'Flutter Demo Home Page'),);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key,this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
Text(
'Hello',style: TextStyle(color: Colors.black,fontSize: 30.0),)
],),floatingactionButton: FloatingactionButton(
onpressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => NextScreen(Bloc())));
},child: Icon(Icons.add),);
}
}
这是要推送的屏幕
class NextScreen extends StatefulWidget {
final _bloc;
NextScreen(this._bloc);
@override
_NextScreenState createState() => _NextScreenState();
}
class _NextScreenState extends State<NextScreen> {
@override
void dispose() {
widget._bloc.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.all(100.0),child: IconButton(
onpressed: () {
Navigator.of(context).pop();
},icon: Icon(Icons.arrow_back),iconSize: 20.0,StreamBuilder<String>(
stream: widget._bloc.stream,builder: (context,snapshot) {
return TextFormField(
controller: widget._bloc.controller,onFieldSubmitted: widget._bloc.submitData(),decoration: InputDecoration(
hintText: 'Enter your name..',errorText: snapshot.data,);
})
],);
}
}
验证用户输入的集团
class Bloc {
TextEditingController _controller;
TextEditingController get controller => _controller;
BehaviorSubject<String> _subject;
BehaviorSubject<String> _validatorSubject;
Stream<String> get stream => _validatorSubject.stream;
void submitData() {
_subject.sink.add(controller.text);
}
void _validate(String text) {
if (!RegExp(r'[0-9]').hasMatch(text)) {
_validatorSubject.sink.add('numbers only');
} else {
_validatorSubject.sink.add(null);
}
}
Bloc() {
_controller = TextEditingController();
_subject = BehaviorSubject<String>();
_validatorSubject = BehaviorSubject<String>();
_subject.stream.listen(_validate);
}
void dispose() {
_subject.close();
_validatorSubject.close();
}
}