屏幕的构造函数每次在该屏幕中发生更改时都被调用

在按下的屏幕中点击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();
  }
}

wangxin071 回答:屏幕的构造函数每次在该屏幕中发生更改时都被调用

打开和关闭键盘将重建整个屏幕。 真正的罪魁祸首是textController:

controller: widget._bloc.controller,

对我有用的解决方案是删除此行。

还可以通过在文本字段中使用onChanged来获取并验证更改后的文本,该文本字段将返回String。 像这样:

.
.
.
 return TextFormField(
       onChanged: widget._bloc.submitData,decoration: InputDecoration
.
.
.

您的submitData()方法将如下所示:

    void submitData(String data) {
    _subject.sink.add(data);
  }
本文链接:https://www.f2er.com/3138166.html

大家都在问