一尘不染

在Flutter中推入新页面时,将重建导航器堆栈上的页面

flutter

我正在开发Flutter应用,该应用会提示您输入一些个人信息。

问题在于,每次发生任何事情 (例如屏幕方向更改或文本字段获得焦点 都会重新构建页面)
键盘立即显示和消失,从而阻止用户键入任何内容 )。

显然,某些事情会触发不必要的重建,但是我找不到什么地方。

当我将此页面作为主页插入时,一切正常。 当在初始屏幕上显示动画后,当我将页面插入其预期位置时,就会发生此问题,因此我认为它与我的问题有关。

主类:

import 'package:flutter/material.dart';
import './view/SplashScreen.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new SplashScreen(),
    );
  }
}

开机画面:

import 'package:flutter/material.dart';
import 'dart:async';
import './UserLoader.dart';

class SplashScreen extends StatefulWidget {
  @override
  _SplashScreenState createState() => new _SplashScreenState();
}

class _SplashScreenState extends State<SplashScreen>
    with SingleTickerProviderStateMixin {
  AnimationController _iconAnimationController;
  CurvedAnimation _iconAnimation;

  @override
  void initState() {
    super.initState();

    _iconAnimationController = new AnimationController(
        vsync: this, duration: new Duration(milliseconds: 2000));

    _iconAnimation = new CurvedAnimation(
        parent: _iconAnimationController, curve: Curves.easeIn);
    _iconAnimation.addListener(() => this.setState(() {}));

    _iconAnimationController.forward();

    startTimeout();
  }

  @override
  Widget build(BuildContext context) {
    return new Material(
      color: Colors.white,
      child: new InkWell(
        child: new Center(
          child: new Container(
            width: 275.0,
            height: 275.0,
            decoration: new BoxDecoration(
              image: new DecorationImage(
                  colorFilter: new ColorFilter.mode(
                      Colors.white.withOpacity(_iconAnimation.value),
                      BlendMode.dstATop),
                  image: new AssetImage("images/logo.png")),
            ),
          ),
        ),
      ),
    );
  }

  void handleTimeout() {
    Navigator.of(context).pushReplacement(new MaterialPageRoute(
        builder: (BuildContext context) => new UserLoader()));
  }

  startTimeout() async {
    var duration = const Duration(seconds: 3);
    return new Timer(duration, handleTimeout);
  }
}

错误页面:

import 'package:flutter/material.dart';

class UserLoader extends StatefulWidget {
  @override
  _UserLoaderState createState() => new _UserLoaderState();
}

class _UserLoaderState extends State<UserLoader> {
  @override
  Widget build(BuildContext context) {
    final _formKey = new GlobalKey<FormState>();
    final _emailController = new TextEditingController();

    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Informations"),
          actions: <Widget>[
            new IconButton(
                icon: const Icon(Icons.save),
                onPressed: () {
                  // unrelated stuff happens here
                })
          ],
        ),
        body: new Center(
          child: new SingleChildScrollView(
              child: new Form(
                  key: _formKey,
                  child: new Column(children: <Widget>[
                    new ListTile(
                      leading: const Icon(Icons.email),
                      title: new TextFormField(
                        decoration: new InputDecoration(
                          hintText: "Email",
                        ),
                        keyboardType: TextInputType.emailAddress,
                        controller: _emailController,
                        validator: _validateEmail,
                      ),
                    ),
                  ]))),
        ));
    }}

有人可以帮我找出为什么页面会不断自我重建吗?


阅读 323

收藏
2020-08-13

共1个答案

一尘不染

我通过简单地更改此类来解决了这个问题:

import 'package:flutter/material.dart';

class UserLoader extends StatefulWidget {
  @override
  _UserLoaderState createState() => new _UserLoaderState();
}

class _UserLoaderState extends State<UserLoader> {
  Widget _form; // Save the form

  @override
  Widget build(BuildContext context) {
    if (_form == null) { // Create the form if it does not exist
      _form = _createForm(context); // Build the form
    }
    return _form; // Show the form in the application
  }

  Widget _createForm(BuildContext context) {
    // This is the exact content of the build method in the question

    final _formKey = new GlobalKey<FormState>();
    final _emailController = new TextEditingController();

    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Informations"),
          actions: <Widget>[
            new IconButton(
                icon: const Icon(Icons.save),
                onPressed: () {
                  // unrelated stuff happens here
                })
          ],
        ),
        body: new Center(
          child: new SingleChildScrollView(
              child: new Form(
                  key: _formKey,
                  child: new Column(children: <Widget>[
                    new ListTile(
                      leading: const Icon(Icons.email),
                      title: new TextFormField(
                        decoration: new InputDecoration(
                          hintText: "Email",
                        ),
                        keyboardType: TextInputType.emailAddress,
                        controller: _emailController,
                        validator: _validateEmail,
                      ),
                    ),
                  ]))),
        ));
    }
  }
}

希望有一天能对别人有所帮助。

2020-08-13