首页 > 解决方案 > 从抽屉导航时抛出的构建错误期间调用的 setState() 或 markNeedsBuild()

问题描述

我正在尝试构建一个具有两个页面的应用程序,即添加人员页面和列出人员页面。正如您在下面的代码中看到的那样,我的应用程序中有一个抽屉。我正在尝试从抽屉导航到添加人员和列表人员页面,如下所示:

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:track_aquintances/listPerson.dart';

class Formscreen extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return FormscreenState();
  }

}

class FormscreenState extends State<Formscreen>{
  DateTime _selectedDate = DateTime.now();

  Widget _buildDateFIeld(){
    return Container(
      padding: const EdgeInsets.all(10),
      child: Center(
        child: Row(
          children: <Widget>[
            Expanded(
              child: Column(
                children: <Widget>[
                  Text(
                    "When did you meet this person?",
                    style: TextStyle(
                      fontSize: 16,
                      fontFamily: 'Montserrat'
                    ),
                  ),
                ],
              )
            )
          ],
        ),
      ),
    );
  }

  Widget _buildNameField(){
    return TextField(
      decoration: InputDecoration(
        icon: Icon(Icons.person),
        labelText: 'Name',
        labelStyle: TextStyle(
          fontFamily: 'Montserrat',
          fontWeight: FontWeight.bold,
          color: Colors.grey
        )
      ),
    );
  }

  Widget _builPhoneField(){
    return TextField(
      keyboardType: TextInputType.number,
      decoration: InputDecoration(
        icon: Icon(Icons.phone),
        labelText: 'Phone Number',
        labelStyle: TextStyle(
          fontFamily: 'Montserrat',
          fontWeight: FontWeight.bold,
          color: Colors.grey
        )
      ),
    );
  }

  Future<Null> _selectDate(BuildContext context) async {
    final DateTime picked = await showDatePicker(
        context: context,
        initialDate: _selectedDate,
        firstDate: DateTime(2015, 8),
        lastDate: DateTime(2101));
    if (picked != null && picked != _selectedDate)
      setState(() {
        _selectedDate = picked;
      });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Center(
          child: Text(
            "Track Acquintances",
            style: TextStyle(
              color: Colors.white,
              fontFamily: 'Montserrat',
              fontWeight: FontWeight.bold
            ),
          ),
        ),
      ),
      drawer: Drawer(
        child: ListView(
          children: <Widget>[
            DrawerHeader(
              decoration: BoxDecoration(
                gradient: LinearGradient(colors: <Color>[ 
                  Colors.teal, Colors.tealAccent
                  ])
              ),
              child: Container(
                child: Column(
                  children: <Widget>[
                    Material(
                      elevation: 10,
                      borderRadius: BorderRadius.all(Radius.circular(50.0)),
                      child: Image.asset('images/corona.JPG', width: 100, height: 100),
                    )
                  ],
                ),
              ),
            ),
            CustomListTile('Add Person', Icons.add, addTapped()),
            CustomListTile('View added People', Icons.people, listTapped(context)),
          ],
        ),
      ),
      body: ListView(
        children: <Widget>[
          Container(
            child: Stack(
              children: <Widget>[
                Container(
                  padding: EdgeInsets.fromLTRB(15.0, 40.0, 0.0, 0.0),
                  child: Text(
                    'Add Person',
                    textAlign: TextAlign.center,
                    style: TextStyle(
                      fontSize: 40.0,
                      color: Colors.teal,
                      fontWeight: FontWeight.bold,
                      fontFamily: 'Montserrat'
                    ),
                  ),
                )
              ],
            )
          ),
          Container(
            padding: EdgeInsets.only(top: 35.0, left: 20.0),
            child: Column(
              children: <Widget>[
                _buildDateFIeld(),
                RaisedButton(
                onPressed: () => _selectDate(context),
                child: Text(
                  'Select date',
                  style: TextStyle(
                      fontFamily: 'Montserrat'
                    ),
                  )
                ),
                _buildNameField(),
                SizedBox(height: 10.0,),
                _builPhoneField(),
                SizedBox(height: 25.0,),
                Container(
                  height: 40.0,
                  child: Material(
                    borderRadius: BorderRadius.circular(20.0),
                    shadowColor: Colors.greenAccent,
                    color: Colors.teal,
                    elevation: 7.0,
                    child: GestureDetector(
                      onTap: () {},
                      child: Center(
                        child: Text(
                          'Add',
                          style: TextStyle(
                            color: Colors.white,
                            fontFamily: 'Montserrat',
                            fontWeight: FontWeight.bold
                          ),
                        ),
                      ),
                    ),
                  ),
                )
              ],
            ),
          )
        ],
      )
    );
  }
}
addTapped(){

}

listTapped(context){
    Navigator.of(context).pop();
    Navigator.of(context).push(MaterialPageRoute(
      builder: (context) => ListPerson()
    ));
}


class CustomListTile extends StatelessWidget{
  final String _name;
  final IconData _icon;
  final Function onTap;

  CustomListTile(this._name, this._icon, this.onTap);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.fromLTRB(9, 0, 9, 0),
      child: Container(
        decoration: BoxDecoration(
          border: Border(bottom: BorderSide(color: Colors.grey))
        ),
        child: InkWell(
          splashColor: Colors.teal,
          onTap: () => onTap,
          child: Container(
            height: 50,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: <Widget>[
                Row(
                  children: <Widget>[
                    Icon(_icon),
                    Padding(
                      padding: EdgeInsets.all(10),
                      child: Text(
                      _name,
                      style: TextStyle(
                        fontSize: 16,
                        fontFamily: 'Montserrat'
                      ),
                    ),
                  )
                  ],
                )
              ],
            ),
          )
        ),
      )
    );
  }
}

我在调试期间收到以下错误:

    The following assertion was thrown while notifying status listeners for AnimationController:
I/flutter (24285): setState() or markNeedsBuild() called during build.
I/flutter (24285): This Overlay widget cannot be marked as needing to build because the framework is already in the
I/flutter (24285): process of building widgets.  A widget can be marked as needing to be built during the build phase
I/flutter (24285): only if one of its ancestors is currently building. This exception is allowed because the framework
I/flutter (24285): builds parent widgets before children, which means a dirty descendant will always be built.
I/flutter (24285): Otherwise, the framework might not visit this widget during this build phase.

任何帮助,将不胜感激。先感谢您。

标签: flutter

解决方案


您可以在下面复制粘贴运行完整代码
listTapped(context)意味着执行listTapped,因此您只需使用listTapped传递函数地址

CustomListTile('View added People', Icons.people, listTapped),

context并传入InWell'sonTap

代码片段

listTapped(BuildContext context) async {
  print("listTapped");
  //Navigator.of(context).pop();
  await Navigator.of(context)
      .push(MaterialPageRoute(builder: (context) => ListPerson()));
  Navigator.of(context).pop();
}
...
child: InkWell(
              splashColor: Colors.teal,
              onTap: () => onTap(context),

工作演示

在此处输入图像描述

完整代码

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

class Formscreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return FormscreenState();
  }
}

class FormscreenState extends State<Formscreen> {
  DateTime _selectedDate = DateTime.now();

  Widget _buildDateFIeld() {
    return Container(
      padding: const EdgeInsets.all(10),
      child: Center(
        child: Row(
          children: <Widget>[
            Expanded(
                child: Column(
              children: <Widget>[
                Text(
                  "When did you meet this person?",
                  style: TextStyle(fontSize: 16, fontFamily: 'Montserrat'),
                ),
              ],
            ))
          ],
        ),
      ),
    );
  }

  Widget _buildNameField() {
    return TextField(
      decoration: InputDecoration(
          icon: Icon(Icons.person),
          labelText: 'Name',
          labelStyle: TextStyle(
              fontFamily: 'Montserrat',
              fontWeight: FontWeight.bold,
              color: Colors.grey)),
    );
  }

  Widget _builPhoneField() {
    return TextField(
      keyboardType: TextInputType.number,
      decoration: InputDecoration(
          icon: Icon(Icons.phone),
          labelText: 'Phone Number',
          labelStyle: TextStyle(
              fontFamily: 'Montserrat',
              fontWeight: FontWeight.bold,
              color: Colors.grey)),
    );
  }

  Future<Null> _selectDate(BuildContext context) async {
    final DateTime picked = await showDatePicker(
        context: context,
        initialDate: _selectedDate,
        firstDate: DateTime(2015, 8),
        lastDate: DateTime(2101));
    if (picked != null && picked != _selectedDate)
      setState(() {
        _selectedDate = picked;
      });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Center(
            child: Text(
              "Track Acquintances",
              style: TextStyle(
                  color: Colors.white,
                  fontFamily: 'Montserrat',
                  fontWeight: FontWeight.bold),
            ),
          ),
        ),
        drawer: Drawer(
          child: ListView(
            children: <Widget>[
              DrawerHeader(
                decoration: BoxDecoration(
                    gradient: LinearGradient(
                        colors: <Color>[Colors.teal, Colors.tealAccent])),
                child: Container(
                  child: Column(
                    children: <Widget>[
                      Material(
                        elevation: 10,
                        borderRadius: BorderRadius.all(Radius.circular(50.0)),
                        child: Image.asset('images/corona.JPG',
                            width: 100, height: 100),
                      )
                    ],
                  ),
                ),
              ),
              CustomListTile('Add Person', Icons.add, addTapped),
              CustomListTile('View added People', Icons.people, listTapped),
            ],
          ),
        ),
        body: ListView(
          children: <Widget>[
            Container(
                child: Stack(
              children: <Widget>[
                Container(
                  padding: EdgeInsets.fromLTRB(15.0, 40.0, 0.0, 0.0),
                  child: Text(
                    'Add Person',
                    textAlign: TextAlign.center,
                    style: TextStyle(
                        fontSize: 40.0,
                        color: Colors.teal,
                        fontWeight: FontWeight.bold,
                        fontFamily: 'Montserrat'),
                  ),
                )
              ],
            )),
            Container(
              padding: EdgeInsets.only(top: 35.0, left: 20.0),
              child: Column(
                children: <Widget>[
                  _buildDateFIeld(),
                  RaisedButton(
                      onPressed: () => _selectDate(context),
                      child: Text(
                        'Select date',
                        style: TextStyle(fontFamily: 'Montserrat'),
                      )),
                  _buildNameField(),
                  SizedBox(
                    height: 10.0,
                  ),
                  _builPhoneField(),
                  SizedBox(
                    height: 25.0,
                  ),
                  Container(
                    height: 40.0,
                    child: Material(
                      borderRadius: BorderRadius.circular(20.0),
                      shadowColor: Colors.greenAccent,
                      color: Colors.teal,
                      elevation: 7.0,
                      child: GestureDetector(
                        onTap: () {},
                        child: Center(
                          child: Text(
                            'Add',
                            style: TextStyle(
                                color: Colors.white,
                                fontFamily: 'Montserrat',
                                fontWeight: FontWeight.bold),
                          ),
                        ),
                      ),
                    ),
                  )
                ],
              ),
            )
          ],
        ));
  }
}

addTapped() {
  print("addTapped");
}

listTapped(BuildContext context) async {
  print("listTapped");
  //Navigator.of(context).pop();
  await Navigator.of(context)
      .push(MaterialPageRoute(builder: (context) => ListPerson()));
  Navigator.of(context).pop();
}

class CustomListTile extends StatelessWidget {
  final String _name;
  final IconData _icon;
  final Function onTap;

  CustomListTile(this._name, this._icon, this.onTap);

  @override
  Widget build(BuildContext context) {
    return Padding(
        padding: EdgeInsets.fromLTRB(9, 0, 9, 0),
        child: Container(
          decoration: BoxDecoration(
              border: Border(bottom: BorderSide(color: Colors.grey))),
          child: InkWell(
              splashColor: Colors.teal,
              onTap: () => onTap(context),
              child: Container(
                height: 50,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: <Widget>[
                    Row(
                      children: <Widget>[
                        Icon(_icon),
                        Padding(
                          padding: EdgeInsets.all(10),
                          child: Text(
                            _name,
                            style: TextStyle(
                                fontSize: 16, fontFamily: 'Montserrat'),
                          ),
                        )
                      ],
                    )
                  ],
                ),
              )),
        ));
  }
}

void main() {
  runApp(MyApp());
}

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

class ListPerson extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("List Person"),
        ),
        body: Text("ListPerson"));
  }
}

推荐阅读