flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
166.29k stars 27.52k forks source link

Failed assertion: boolean expression must not be nullError came up after form pop the data #55074

Closed ShinLv closed 4 years ago

ShinLv commented 4 years ago

I'm working on a To-Do-List like UI which you type in your title & description(File 1) and render in a screen (File 2). These files works totally fine in a separated flutter project when File 1 is my 'home page'. But when I copy n paste the same code back to my master flutter project(where File 1 is one of the screen from bottom navigator), the 'boolean expression' error appeared. Anybody has a clue?

=============Dart File 1: Add New============= import 'package:flutter/material.dart'; import 'package:grdd_lite/model/model_invitation.dart';

class NewTodoView extends StatefulWidget { final Invitation item;

NewTodoView({ this.item });

@override _NewTodoViewState createState() => _NewTodoViewState(); }

class _NewTodoViewState extends State { TextEditingController titleController; TextEditingController descController;

String _title, _desc; final formKey = GlobalKey();

@override void initState() { super.initState(); titleController = new TextEditingController( text: widget.item != null ? widget.item.title : null ); descController = new TextEditingController( text: widget.item != null ? widget.item.desc : null ); }

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text( widget.item != null ? 'Edit todo' : 'New todo', key: Key('new-item-title'), ), centerTitle: true, ), body: Padding( padding: const EdgeInsets.all(8.0), child: Form( key: formKey, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ TextFormField( controller: titleController, maxLength: 20, autofocus: true, onEditingComplete: submit, decoration: InputDecoration(labelText: 'Title'), validator: (input) => input.length > 10 ? 'Title is too short' : null, onSaved: (input) => _title = input, ), SizedBox(height: 14.0,), TextFormField( controller: descController, autofocus: true, onEditingComplete: submit, decoration: InputDecoration(labelText: 'Description'), //validator: , onSaved: (input) => _desc = input, ), SizedBox(height: 14.0,), RaisedButton( color: Theme.of(context).primaryColor, child: Text( 'Save', style: TextStyle( color: Theme.of(context).primaryTextTheme.title.color ), ), elevation: 3.0, onPressed: () { submit(); }, ) ], ), ), ), ); }

void submit(){ if(formKey.currentState.validate()) { formKey.currentState.save(); Navigator.of(context).pop(Invitation(title: _title, desc: _desc)); } } }

===========Dart file 2: Main UI Screen========== import 'package:flutter/material.dart'; import 'package:grdd_lite/model/model_invitation.dart'; import 'package:grdd_lite/components/ctn_expansioncard.dart'; import 'package:grdd_lite/screens/scrn_invitation_new.dart';

class MyInvitation extends StatefulWidget { @override _MyInvitationState createState() => _MyInvitationState(); }

class _MyInvitationState extends State with TickerProviderStateMixin { List items = new List(); GlobalKey animatedListKey = GlobalKey(); AnimationController emptyListController;

@override void initState() { emptyListController = AnimationController( vsync: this, duration: Duration(milliseconds: 200), ); emptyListController.forward(); super.initState(); }

@override Widget build(BuildContext context) { return Scaffold( appBar: PreferredSize( preferredSize: Size.fromHeight(0.0), child: AppBar(), ), floatingActionButton: FloatingActionButton( child: Icon(Icons.add), onPressed: () =>goToNewItemView(), ), body: renderBody() ); }

Widget renderBody(){ if(items.length > 0){ return buildListView(); }else{ return emptyList(); } }

Widget emptyList(){ return Center( child: FadeTransition( opacity: emptyListController, child: Text('No items') ) ); }

Widget buildListView() { return AnimatedList( key: animatedListKey, initialItemCount: items.length, itemBuilder: (BuildContext context, int index, animation){ return SizeTransition( sizeFactor: animation, child: buildListTile(items[index], index), ); }, ); }

Widget buildListTile(item, index){ bool _value = item.activated; return ExpansionCard( key: Key('${item.hashCode}'), //onLongPress: () => goToEditItemView(item), title: Text( item.title, key: Key('item-$index'), style: TextStyle( fontSize: 20, color: item.activated ? Colors.black : Colors.black26, ), ), trailing: Switch( key: Key('activated-icon-$index'), activeColor: Colors.black87, value: _value, onChanged: (bool _value) => changeItemCompleteness(item) ), body: Text( item.desc, key: Key('item-$index-desc'), ), ); }

void changeItemCompleteness(Invitation item){ setState(() { item.activated = !item.activated; }); }

void goToNewItemView(){ Navigator.of(context).push(MaterialPageRoute(builder: (context){ return NewTodoView(); })).then((title){ if(title != null) { addItem(Invitation(title: title.title, desc: title.desc)); } }); }

void addItem(Invitation item){ // Insert an item into the top of our list, on index zero items.insert(0, item); if(animatedListKey.currentState != null) animatedListKey.currentState.insertItem(0); }

void goToEditItemView(Invitation item){ Navigator.of(context).push(MaterialPageRoute(builder: (context){ return NewTodoView(item: item); })).then((title){ if(title != null) { editItem(item, title); } }); }

void editItem(Invitation item ,String title){ item.title = title; }

void removeItemFromList(Invitation item, int index) { animatedListKey.currentState.removeItem(index, (context, animation){ return SizedBox(width: 0, height: 0,); }); deleteItem(item);

}

void deleteItem(Invitation item){ items.remove(item); if(items.isEmpty) { emptyListController.reset(); setState(() {}); emptyListController.forward(); } } }

lock[bot] commented 4 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.