从抽屉中导航时抛出构建错误期间调用setState()或markNeedsBuild()

时间:2020-03-22 10:08:58

标签: flutter

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

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.

任何帮助将不胜感激。预先谢谢你。

1 个答案:

答案 0 :(得分:1)

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

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

并在context的{​​{1}}中传递InWell

代码段

onTap

工作演示

enter image description here

完整代码

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),