Closed ShinLv closed 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.
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(); } } }