How to have the text from a selected item inside a text field in flutter - flutter

I have an edit function which displays in a dialog in my to do list app on flutter. When an item is selected to be edited, a dialog containing a TextField(to enter the new value of the selected item) and a button(to save the changes) appears. The goal is to have the text of the selected item on the TextField of the dialog, currently my code has a hintText inside the TextField that does display the value of the selected item but what I want to achieve is to have that in the controller.
If you didnt understood what I want to achieve see this edit function like instagram's one, when editing a post on instagram you don't have to type everything again instead when editing you have the original text of the post there. Well that is not happening on my app, when editing an item the TextField doesnt show anything. How can I make this work?
code related to the edit function
List<ToDoElement> _toDoItems = [];
TextEditingController _editController = TextEditingController();
void _editToDoItem(String newText, int index) {
setState(() {
_toDoItems[index].task = newText;
});
}
_editDialog(BuildContext context, int index) {
return showDialog(context: context, builder: (context){
return Dialog(
backgroundColor: Colors.transparent,
insetAnimationDuration:
const Duration(milliseconds: 800),
child: Container(
padding: EdgeInsets.all(20),
height: 180,
width: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 60,
child: TextField( // this is the textfield that I should have the text of the selected item inside.
controller: _editController,
autofocus: true,
autocorrect: false,
onSubmitted: (val) {
FocusScope.of(context).requestFocus(FocusNode());
_editToDoItem(val, index);
Navigator.of(context).pop();
},
decoration: InputDecoration(
hintText: '${_toDoItems[index].task}', //this hint text shows the value of the selected item, yhis is what I want to have but in the controller.
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
),
)
),
Container(
height: 65,
width: double.infinity,
margin: EdgeInsets.only(top: 5,),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('EDIT', style: TextStyle(fontSize: 18)),
onPressed: () {
_editToDoItem(_editController.text, index);
FocusScope.of(context).requestFocus(FocusNode());
Navigator.of(context).pop();
},
),
),
],
),
),
);
});
}
full main.dart
import 'package:flutter/material.dart';
class ToDoElement {
String task;
final DateTime timeOfCreation;
ToDoElement(this.task, this.timeOfCreation);
}
void main() => runApp(MaterialApp(home: MyApp()));
class MyApp extends StatefulWidget {
#override
createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
List<ToDoElement> _toDoItems = [];
TextEditingController _controller = TextEditingController();
TextEditingController _editController = TextEditingController();
void _addToDoItem(String task) {
if(task.isNotEmpty) {
setState(() {
_toDoItems.add(ToDoElement(task, DateTime.now()));
});
}
}
void _editToDoItem(String newText, int index) {
setState(() {
_toDoItems[index].task = newText;
});
}
void _removeTodoItem(int index) {
setState(() => _toDoItems.removeAt(index));
}
_editDialog(BuildContext context, int index) {
return showDialog(context: context, builder: (context){
return Dialog(
backgroundColor: Colors.transparent,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)
),
insetAnimationDuration:
const Duration(milliseconds: 800),
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20.0)),
),
padding: EdgeInsets.all(20),
height: 180,
width: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 60,
child: TextField(
controller: _editController,
autofocus: true,
autocorrect: false,
onSubmitted: (val) {
FocusScope.of(context).requestFocus(FocusNode());
_editToDoItem(val, index);
Navigator.of(context).pop();
},
style: TextStyle(fontSize: 17,),
decoration: InputDecoration(
hintText: '${_toDoItems[index].task}',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
),
)
),
Container(
height: 65,
width: double.infinity,
margin: EdgeInsets.only(top: 5,),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('EDIT', style: TextStyle(fontSize: 18)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
onPressed: () {
_editToDoItem(_editController.text, index);
FocusScope.of(context).requestFocus(FocusNode());
Navigator.of(context).pop();
},
),
),
],
),
),
);
});
}
Widget _buildToDoItem(String toDoText, int index) {
return SizedBox(
child: Container(
height: 58,
margin: EdgeInsets.only(left: 22.0, right: 22.0, bottom: 12,),
decoration: BoxDecoration(
border: Border.all(width: 1.5, color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(18)),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children:[
Expanded(
child: ListTile(
title: Text(
toDoText,
style: TextStyle(fontSize: 18),
),
onTap: () => null,
),
),
FlatButton(
child: Text('Edit', style: TextStyle(color: Colors.red, fontSize: 16.5),),
onPressed: () => _editDialog(context, index),
),
FlatButton(
child: Text('Delete', style: TextStyle(color: Colors.red, fontSize: 16.5),),
onPressed: () => _removeTodoItem(index),
),
],
),
),
);
}
int compareElement(ToDoElement a, ToDoElement b) =>
a.timeOfCreation.isAfter(b.timeOfCreation) ? -1 : 1;
Widget _buildToDoList() {
_toDoItems.sort(compareElement);
return Expanded(
child: ListView.builder(
itemCount: _toDoItems.length,
itemBuilder: (context, index) {
if (index < _toDoItems.length) {
return _buildToDoItem(_toDoItems[index].task, index);
}
},
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(50),
child: AppBar(
centerTitle: true,
backgroundColor: Colors.red,
title: Text('To Do List', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold,),),
)
),
backgroundColor: Colors.white,
body: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 60,
margin: EdgeInsets.all(22),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 10,
child: Container(
height: double.infinity,
child: TextField(
controller: _controller,
autofocus: true,
onSubmitted: (val) {
_addToDoItem(val);
_controller.clear();
},
style: TextStyle(fontSize: 18,),
decoration: InputDecoration(
hintText: 'Add a task here...',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
),
),
),
),
Expanded(
flex: 4,
child: Container(
height: double.infinity,
margin: EdgeInsets.only(left: 12),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('ADD', style: TextStyle(fontSize: 18)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
onPressed: () {
_addToDoItem(_controller.text);
_controller.clear();
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
),
],
),
),
_buildToDoList()
]
),
),
);
}
}
If you have any questions please let me know in the comments;)

You already have the _editController variable. You can use it not only to get the typed text but also to set it:
You can do it before calling the edit function, for example:
[...]
onPressed: () {
_editController.text = toDoText;
_editDialog(context, index);
},
[...]
(Or maybe before creating the dialog, if you prefer.)
As you can see in the documentation:
A TextEditingController can also be used to provide an initial value for a text field. If you build a text field with a controller that already has text, the text field will use that text as its initial value.

Related

Query not working correctly when searching ListView with TextFormField

I am listing records from Firebase Firestore with ListView.builder. I convert the incoming records to Model and list them.
I made a search option and I'm trying to make a filtering system for it. I want to filter by nameSurname search, city and district value.
I wrote a code like this:
StreamBuilder(
stream: db
.collection("NeedClothesPeople")
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
} else {
final searchText = searchController.text.trim().toLowerCase();
final List<NeedClothesPeopleModel> data = snapshot.data!.docs
.map((e) => NeedClothesPeopleModel.fromDocument(e))
.where((e) =>
searchText.isEmpty ||
e.nameSurname!.toLowerCase().contains(searchText) &&
selectedCity.isEmpty ||
e.city == selectedCity && selectedDistrict.isEmpty ||
e.district == selectedDistrict) // filter
.toList();
return Column(
children: [
const SizedBox(height: 10),
SizedBox(
width: MediaQuery.of(context).size.width * 0.95,
child: TextFormField(
controller: searchController,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.search),
suffixIcon: IconButton(
icon: Icon(Icons.settings),
onPressed: () {
filterModalBottomSheet(context);
},
),
contentPadding: const EdgeInsets.only(),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
),
),
onChanged: (value) {
setState(() {});
},
),
),
SizedBox(
width: double.infinity,
height: MediaQuery.of(context).size.height * 0.8,
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: data.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: Icon(Icons.person),
title: Text(data[index].nameSurname.toString()),
subtitle: Text(
"${data[index].city} / ${data[index].district}",
),
trailing: IconButton(
icon: const Icon(Icons.info),
onPressed: () {
Get.to(const NeedClothesPeopleDetailPage(),
arguments: data[index]);
print(data[index].nameSurname);
},
),
),
);
},
),
),
],
);
}
},
),
void filterModalBottomSheet(BuildContext context) {
showModalBottomSheet(
isScrollControlled: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(50),
topRight: Radius.circular(50),
),
),
context: context,
builder: (context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return SizedBox(
height: MediaQuery.of(context).size.height * 0.5,
child: Padding(
padding: const EdgeInsets.only(left: 8, right: 8),
child: Column(
children: [
SizedBox(
height: MediaQuery.of(context).size.height * 0.04,
),
Row(
children: [
const Expanded(
flex: 1,
child: Text(
"İl:",
style: TextStyle(fontSize: 19),
),
),
Expanded(
flex: 9,
child: DropdownButtonFormField(
hint: const Text("İl seçiniz"),
decoration: InputDecoration(
prefixIcon: const Icon(
Icons.location_city,
color: Color(0xFFCB3126),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
borderSide: const BorderSide(
color: Color(0xFFCB3126),
),
),
),
items: citys
.map(
(e) => DropdownMenuItem<String>(
value: e.value,
child: e.child,
),
)
.toList(),
onChanged: (value) {
setState(() {
selectedCity = value.toString();
});
},
),
),
],
),
const SizedBox(height: 20),
Row(
children: [
const Expanded(
flex: 1,
child: Text(
"İlçe:",
style: TextStyle(fontSize: 19),
),
),
Expanded(
flex: 9,
child: DropdownButtonFormField(
key: getCityKey(),
hint: selectedCity == ""
? const Text("Önce il seçiniz")
: const Text("İlçe seçiniz"),
decoration: InputDecoration(
prefixIcon: const Icon(
Icons.location_city,
color: Color(0xFFCB3126),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(50),
borderSide: const BorderSide(
color: Color(0xFFCB3126),
),
),
),
items: districtsItem(),
onChanged: (value) {
setState(() {
selectedDistrict = value.toString();
});
},
),
),
],
),
const Spacer(),
Padding(
padding: const EdgeInsets.only(left: 12, right: 12),
child: SizedBox(
width: double.infinity,
height: 50,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFCB3126),
),
child: const Text(
"Filtrele",
style: TextStyle(fontSize: 20),
),
onPressed: () {
setState(() {
filterActive = true;
Navigator.pop(context);
print(filterActive);
});
},
),
),
),
const SizedBox(height: 10),
],
),
),
);
},
);
},
);
}
The problem is this: When I call it by typing in TextFormField, the records in ListView.builder are changing. However, when filtering is done, the records do not change on the screen.
Why could this be? How can I solve the problem? Thanks.

Creating an flutter app in vs code with firebase its showing the specific errors .Errors that showing is mentioned below and the signup widget code

'The name UserRecord isn't a type so it can't be used as a type argument Try correcting the name to an existing type or defining a type named UserRecord
The method 'queryUserRecordOnce' isn't defined for the type '_SignupWidgetState'.
Try correcting the name to the name of an existing method, or defining a method named 'queryUserRecordOnce'
The method 'createUserRecordData' isn't defined for the type '_SignupWidgetState'.
Try correcting the name to the name of an existing method, or defining a method named 'createUserRecordData''
*import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'login.dart';
import 'package:easy_debounce/easy_debounce.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:easy_debounce/easy_debounce.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:google_fonts/google_fonts.dart';
class SignupWidget extends StatefulWidget {
const SignupWidget({Key key}) : super(key: key);
#override
_SignupWidgetState createState() => _SignupWidgetState();
}
class _SignupWidgetState extends State<SignupWidget> {
TextEditingController emailTextController;
TextEditingController textController1;
TextEditingController textController2;
TextEditingController passwordTextController;
bool passwordVisibility;
var collection = FirebaseFirestore.instance.collection('UserRecord');
final auth = FirebaseAuth.instance;
final scaffoldKey = GlobalKey<ScaffoldState>();
#override
void initState() {
super.initState();
emailTextController = TextEditingController();
textController1 = TextEditingController();
textController2 = TextEditingController();
passwordTextController = TextEditingController();
passwordVisibility = false;
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: scaffoldKey,
body: SafeArea(
child: GestureDetector(
onTap: () => FocusScope.of(context).unfocus(),
child: Align(
alignment: AlignmentDirectional(0.3, -0.8),
child: Container(
width: double.infinity,
height: double.infinity,
decoration: BoxDecoration(
color: Color(0xFFEEEEEE),
),
child: Padding(
padding: EdgeInsetsDirectional.fromSTEB(0, 100, 0, 0),
child: ListView(
padding: EdgeInsets.zero,
shrinkWrap: true,
scrollDirection: Axis.vertical,
children: [
Align(
alignment: AlignmentDirectional(0.2, -0.35),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Align(
alignment: AlignmentDirectional(-0.55, -0.35),
child: InkWell(
onTap: () async {
Navigator.pop(context);
},
child: const FaIcon(
FontAwesomeIcons.arrowLeft,
color: Color.fromRGBO(5, 4, 0, 5),
size: 24,
),
),
),
),
const Expanded(
child: Align(
alignment: AlignmentDirectional(-2.5, -0.1),
child: Text(
'Signup',
style: TextStyle(
fontFamily: 'Oswald',
color: Color(0xFF0F5AA5),
fontSize: 40,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
Align(
alignment: AlignmentDirectional(0, 0),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Align(
alignment: AlignmentDirectional(0, 0.05),
child: Container(
width: 250,
height: 400,
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xFF0F5AA5),
Color(0xFF0F5AA5),
],
stops: [0, 0, 1],
begin: AlignmentDirectional(0, -1),
end: AlignmentDirectional(0, 1),
),
),
alignment: AlignmentDirectional(
-0.09999999999999998, 0.5),
child: Align(
alignment: AlignmentDirectional(-0.1, 1),
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
10, 15, 10, 0),
child: TextFormField(
controller: emailTextController,
onChanged: (_) => EasyDebounce.debounce(
'emailTextController',
Duration(milliseconds: 2000),
() => setState(() {}),
),
autofocus: true,
obscureText: false,
decoration: InputDecoration(
hintText: 'Mobile or Email',
hintStyle: const TextStyle(
fontFamily: 'Poppins',
color: Color(0xFF000509),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0xFF080F18),
width: 1,
),
borderRadius:
BorderRadius.circular(5),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0xFF080F18),
width: 1,
),
borderRadius:
BorderRadius.circular(5),
),
suffixIcon: emailTextController
.text.isNotEmpty
? InkWell(
onTap: () => setState(
() => emailTextController
?.clear(),
),
child: Icon(
Icons.clear,
color: Color(0xFF757575),
size: 22,
),
)
: null,
),
style: TextStyle(
fontFamily: 'Poppins',
color: Color(0xFF1A1F24),
),
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
10, 10, 10, 0),
child: TextFormField(
controller: textController1,
onChanged: (_) => EasyDebounce.debounce(
'textController1',
Duration(milliseconds: 1000),
() => setState(() {}),
),
autofocus: true,
obscureText: false,
decoration: InputDecoration(
hintText: 'Full name',
hintStyle: TextStyle(
fontFamily: 'Poppins',
color: Color(0xFF000509),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0xFF080F18),
width: 1,
),
borderRadius:
BorderRadius.circular(5),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0xFF080F18),
width: 1,
),
borderRadius:
BorderRadius.circular(5),
),
suffixIcon: textController1
.text.isNotEmpty
? InkWell(
onTap: () => setState(
() => textController1
?.clear(),
),
child: Icon(
Icons.clear,
color: Color(0xFF757575),
size: 22,
),
)
: null,
),
style: TextStyle(
fontFamily: 'Poppins',
color: Color(0xFF1A1F24),
),
textAlign: TextAlign.start,
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
10, 10, 10, 0),
child: TextFormField(
controller: textController2,
onChanged: (_) => EasyDebounce.debounce(
'textController2',
Duration(milliseconds: 1000),
() => setState(() {}),
),
autofocus: true,
obscureText: false,
decoration: InputDecoration(
hintText: 'User name',
hintStyle: TextStyle(
fontFamily: 'Poppins',
color: Color(0xFF000509),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0xFF080F18),
width: 1,
),
borderRadius:
BorderRadius.circular(5),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0xFF080F18),
width: 1,
),
borderRadius:
BorderRadius.circular(5),
),
suffixIcon: textController2
.text.isNotEmpty
? InkWell(
onTap: () => setState(
() => textController2
?.clear(),
),
child: Icon(
Icons.clear,
color: Color(0xFF757575),
size: 22,
),
)
: null,
),
style: TextStyle(
fontFamily: 'Poppins',
color: Color(0xFF1A1F24),
),
textAlign: TextAlign.start,
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
10, 10, 10, 25),
child: FutureBuilder<List<UserRecord>>(
future: queryUserRecordOnce(
singleRecord: true,
),
builder: (context, snapshot) {
// Customize what your widget looks like when it's loading.
if (!snapshot.hasData) {
return const Center(
child: SizedBox(
width: 50,
height: 50,
child:
CircularProgressIndicator(
color: Colors.black,
),
),
);
}
List<UserRecord>
textFieldUserRecordList =
snapshot.data;
final textFieldUserRecord =
textFieldUserRecordList.isNotEmpty
? textFieldUserRecordList
.first
: null;
return TextFormField(
controller: passwordTextController,
onChanged: (_) =>
EasyDebounce.debounce(
'passwordTextController',
Duration(milliseconds: 1000),
() => setState(() {}),
),
autofocus: true,
obscureText: !passwordVisibility,
decoration: InputDecoration(
hintText: 'Password',
hintStyle: TextStyle(
fontFamily: 'Poppins',
color: Color(0xFF000509),
),
enabledBorder:
UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0xFF080F18),
width: 1,
),
borderRadius:
BorderRadius.circular(5),
),
focusedBorder:
UnderlineInputBorder(
borderSide: BorderSide(
color: Color(0xFF080F18),
width: 1,
),
borderRadius:
BorderRadius.circular(5),
),
suffixIcon: InkWell(
onTap: () => setState(
() => passwordVisibility =
!passwordVisibility,
),
focusNode: FocusNode(
skipTraversal: true),
child: Icon(
passwordVisibility
? Icons
.visibility_outlined
: Icons
.visibility_off_outlined,
color: Color(0xFF757575),
size: 22,
),
),
),
style: TextStyle(
fontFamily: 'Poppins',
color: Color(0xFF1A1F24),
),
textAlign: TextAlign.start,
);
},
),
),
Padding(
padding: EdgeInsetsDirectional.fromSTEB(
0, 0, 0, 30),
child: ElevatedButton(
onPressed: () async {
final user = await FirebaseAuth
.instance
.createUserWithEmailAndPassword(
email:
emailTextController.text,
password:
passwordTextController
.text);
if (user == null) {
return;
}
final userCreateData =
createUserRecordData(
username: textController2.text,
pass: passwordTextController.text,
email: emailTextController.text,
uid: textController1.text,
);
await UserRecord.collection
.doc(user.uid)
.update(userCreateData);
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
LoginWidget(),
),
);
},
child: Text("signup"),
),
),
],
),
),
),
),
],
),
),
],
),
),
),
),
),
),
);
}
}*

Flutter Bloc Not updating immediately, only after a refresh or rebuild

I am working on a flutter project, so I was trying to use Flutter bloc state management. I built everything from state to event and also the bloc thing. like the code below:
State:
abstract class UserState extends Equatable {
const UserState();
#override
List<Object> get props => [];
}
class UserInitialState extends UserState {}
class UserLoadingState extends UserState {
#override
List<Object> get props => [];
}
class UserLoadedState extends UserState {
final UserModel user;
const UserLoadedState(this.user);
#override
List<Object> get props => [user];
}
class UserValidationState extends UserState {
final Map<String, dynamic> validation;
const UserValidationState(this.validation);
#override
List<Object> get props => [validation];
}
class UserErrorState extends UserState {
final Map<String, dynamic> error;
const UserErrorState(this.error);
#override
List<Object> get props => [error];
}
Event:
class LoginUserEvent extends UserEvent {
final String email, password;
const LoginUserEvent({this.email, this.password});
#override
List<Object> get props => [];
}
Bloc:
UserBloc(this._userReprository) : super(UserInitialState()) {
on<LoginUserEvent>((event, emit) async {
emit(UserLoadingState());
try {
await _userReprository
.loginUser(
email: event.email,
password: event.password,
)
.then((result) {
if (result.contains('success')) {
emit(UserLoadedState(result[1]));
} else if (result.contains('errors')) {
emit(UserValidationState(result[1]));
}
});
} catch (e) {
emit(UserErrorState(e));
}
});
}
so it should work like when I click on the button it switch to loading event then after response it either load or throw a validation error or it catch an error if something happened.
well unfortunately the UI is not updating immedtialy, only after a second refresh or a setstate of another way or something that rebuild it it only change
Here is the code of the UI:
#override
Widget build(BuildContext context) {
final deviceSize = MediaQuery.of(context).size;
// Clearing all TextEdititng Controller Values
_clearValues() {
_email.clear();
_password.clear();
_valErrors.clear();
}
return Scaffold(
body: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
margin: EdgeInsets.only(top: deviceSize.height * 0.05),
child: Column(
children: [
Container(
margin: const EdgeInsets.symmetric(vertical: 20),
child: Material(
shadowColor: Colors.black54,
color: Theme.of(context).colorScheme.primary,
elevation: 2,
borderRadius: BorderRadius.circular(35),
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10,
horizontal: 15,
),
child: SvgPicture.asset(
'./assets/img/auth_logo.svg',
width: deviceSize.width * 0.5,
height: deviceSize.width * 0.5,
),
),
),
),
const SizedBox(
height: 10,
),
Column(
children: <Widget>[
Container(
margin: const EdgeInsets.symmetric(horizontal: 20),
child: Material(
borderRadius: BorderRadius.circular(25),
elevation: 2,
shadowColor: Colors.black54,
child: TextField(
keyboardType: TextInputType.emailAddress,
textInputAction: TextInputAction.next,
controller: _email,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.email),
border: OutlineInputBorder(
borderSide: const BorderSide(
color: Colors.white, width: 32.0),
borderRadius: BorderRadius.circular(25.0),
),
labelText: 'Email',
),
),
),
),
_valErrors.containsKey('email')
? Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 30,
vertical: 1,
),
child: Text(
_valErrors['email'],
textAlign: TextAlign.start,
style: const TextStyle(
color: Colors.red,
),
),
),
),
const SizedBox(
height: 15,
)
],
)
: const SizedBox(
height: 25,
),
],
),
Container(
margin: const EdgeInsets.symmetric(horizontal: 20),
child: Material(
elevation: 2,
shadowColor: Colors.black54,
borderRadius: BorderRadius.circular(25),
child: TextField(
textInputAction: TextInputAction.done,
obscureText: hiddenContent,
controller: _password,
keyboardType: TextInputType.text,
decoration: InputDecoration(
prefixIcon: const Icon(Icons.lock),
suffixIcon: IconButton(
icon: hiddenContent
? const Icon(Icons.visibility)
: const Icon(Icons.visibility_off),
onPressed: () {
setState(() {
hiddenContent = !hiddenContent;
});
}),
border: OutlineInputBorder(
borderSide:
const BorderSide(color: Colors.white, width: 32.0),
borderRadius: BorderRadius.circular(25.0),
),
labelText: 'Password',
),
),
),
),
_valErrors.containsKey('password')
? Column(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 30, vertical: 1),
child: Text(
_valErrors['password'],
textAlign: TextAlign.start,
style: const TextStyle(
color: Colors.red,
),
),
),
),
const SizedBox(
height: 15,
)
],
)
: const SizedBox(
height: 25,
),
BlocBuilder<UserBloc, UserState>(
builder: (context, state) {
if (state is UserLoadingState) {
return const CircularProgressIndicator();
}
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Material(
elevation: 2,
shadowColor: Colors.black54,
borderRadius: BorderRadius.circular(25),
child: TextButton(
style: ButtonStyle(
padding: MaterialStateProperty.all<EdgeInsets>(
const EdgeInsets.symmetric(
vertical: 15,
horizontal: 30,
),
),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
),
backgroundColor: MaterialStateProperty.all<Color>(
Theme.of(context).colorScheme.primary,
),
),
onPressed: () async {
// If Statement to make sure THe validation is correct and to show Messages
setState(() {
if (_email.text.isEmpty) {
_valErrors['email'] = 'This Field is Required';
} else {
_valErrors.remove('email');
}
if (_password.text.isEmpty) {
_valErrors['password'] =
'This Field is Required';
} else if (_password.text.length < 8) {
_valErrors['password'] =
'Password must be Greater Than 8';
} else {
_valErrors.remove('password');
}
});
// Databse Function Login
if (_valErrors.isEmpty) {
context.read<UserBloc>().add(
LoginUserEvent(
email: _email.text,
password: _password.text,
),
);
if (state is UserLoadedState) {
_clearValues();
Navigator.of(context)
.pushReplacementNamed('/botnavbar');
} else if (state is UserValidationState) {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text(
'There is some problems'),
content: Text(state
.validation['message']
.toString()),
actions: <Widget>[
TextButton(
onPressed: () =>
Navigator.of(context).pop(),
child: const Text('Okay'),
),
],
);
});
}
}
},
child: const Text(
'Login',
style: TextStyle(
fontSize: 20,
color: Colors.white,
),
),
),
),
Material(
elevation: 2,
shadowColor: Colors.black54,
borderRadius: BorderRadius.circular(25),
child: TextButton(
style: ButtonStyle(
padding: MaterialStateProperty.all<EdgeInsets>(
const EdgeInsets.symmetric(
vertical: 15,
horizontal: 35,
),
),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
side: BorderSide(
color: Theme.of(context).colorScheme.primary,
),
),
),
),
onPressed: () {
Navigator.of(context)
.pushReplacementNamed('/register');
},
child: Text(
'Register',
style: TextStyle(
fontSize: 20,
color: Theme.of(context).colorScheme.primary,
),
),
),
),
],
);
},
),
],
),
),
),
);
}
I tried to use the blocbuilder on the whole scaffold but still the same problem
Hope you can help me guys

How to show an alert dialog after the user click the button in flutter

I'm new in flutter and I'm trying to show a dialog alert for the result if the user click on "Calculate" button. I want to change the "Text" result into the dialog alert like "The prediction of (total days) is (result)" Anyone can help me how to do this? I can't find any suitable resource for this, Thank you
class TransactionYearly extends StatefulWidget {
#override
_TransactionYearlyState createState() => _TransactionYearlyState();
}
class _TransactionYearlyState extends State<TransactionYearly> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final TextEditingController amount = new TextEditingController();
final TextEditingController day = new TextEditingController();
double _result;
#override
void initState() {
super.initState();
}
#override
void dispose() {
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(getTranslated(context, 'prediction_calculation'),),
elevation: 0,
brightness: Brightness.light,
backgroundColor: primary,
leading: IconButton(
onPressed: (){
Navigator.pop(context, MaterialPageRoute(builder: (context) => Transactions()));
},
icon: Icon(Icons.arrow_back_ios,
size: 20,
color: Colors.black,),
),
),
body: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
Container(
height: 300,
child: Image(
image: AssetImage("assets/girlsave.png"),
fit: BoxFit.contain,
),
),
Container(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
Container(
child: TextFormField(
validator: (input) {
if (input.isEmpty) return 'Please fill up the text fields';
},
controller: amount,
decoration: InputDecoration(
labelText: getTranslated(context, 'amount_text'),
labelStyle: TextStyle(color: Colors.grey),
prefixIcon: Icon(
Icons.attach_money,
color: secondary,
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: secondary),
),
),
keyboardType: TextInputType.number,
),
),
Container(
child: TextFormField(
validator: (input) {
if (input.isEmpty)
return 'Please fill up the text fields';
},
controller: day,
decoration: InputDecoration(
labelText: getTranslated(context, 'day_text'),
labelStyle: TextStyle(color: Colors.grey),
prefixIcon: Icon(
Icons.date_range_outlined,
color: secondary,
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: secondary),
),
),
keyboardType: TextInputType.number,
),
),
SizedBox(height: 20),
Container(
padding: EdgeInsets.only(
top: 25.0, left: 20.0, right: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget> [
Expanded (
child: ElevatedButton(
onPressed: () {
if(!_formKey.currentState.validate()){
return;
}
_formKey.currentState.save();
calculate();
},
child: Text(getTranslated((context), "calculate_button").toUpperCase(), style: TextStyle (
fontSize: 14,
)),
style: ButtonStyle(
padding: MaterialStateProperty.all<EdgeInsets>(EdgeInsets.all(15)),
foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
backgroundColor: MaterialStateProperty.all<Color>(Colors.pink),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
side: BorderSide(color: secondary)
),
),
),
),
),
SizedBox(width: 20, height: 10),
Expanded(
child: ElevatedButton(
onPressed: () {
amount.clear();
day.clear();
},
child: Text(getTranslated((context), "clear_button").toUpperCase(), style: TextStyle (
fontSize: 14
)),
style: ButtonStyle(
padding: MaterialStateProperty.all<EdgeInsets>(EdgeInsets.all(15)),
foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
backgroundColor: MaterialStateProperty.all<Color>(Colors.pink),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
side: BorderSide(color: secondary)
),
),
),
),
)
],
)
),
Text(
_result == null ? "Enter amount" : "$_result",
)
],
),
),
),
],
),
),
));
}
void calculate(){
double amounts = double.parse(amount.text);
double days = double.parse(day.text);
double result = amounts * days;
_result = result;
setState(() {
});
}
}
After calculate call you can show dialog like this in the onPressed function.
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Result'),
content: Text('Result is $_result'),
actions: [
ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: Text('Go Back'))
],
),
);

How to edit a selected item from a list in flutter

I have been trying to add an edit function to my to do list in which a user can select the item the user wants to edit, then that should pop a dialog where there is a textfield to enter the new value of the selected item and a Button that saves the changes. Currently I have a function that calls the array where the tasks are stored then it is supposed to triger the selected item using index so that at the end that selected value could be given a new value when onPressed, see this edit functionality as instagrams one except it edits text.
The problem comes when calling that function into the dialog's edit button because I am doing it like this onPressed: () => _editToDoItem(_controller.text, index) and since I have to pass 2 parameters there, the error I am getting is Undefined name 'index'. How can this problem be solved to make this edit function work?. By the way, I haven't get to try the edit function because of this error so please correct me if the function or any part of the code is incorrect.
everything to do with the edit function below.
List<ToDoElement> _toDoItems = [];
TextEditingController _controller = TextEditingController();
// this function adds a task to the list
void _addToDoItem(String task) {
if(task.isNotEmpty) {
setState(() {
_toDoItems.add(ToDoElement(task, DateTime.now()));
});
}
}
// this is the function that is supposed to edit the selected index from the _toDoItems array
void _editToDoItem(String newText, int index) {
setState(() {
_toDoItems[index].task = newText;
});
}
_editDialog(BuildContext context) {
return showDialog(context: context, builder: (context) {
return Dialog(
child: Container(
height: 180,
width: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 60,
child: TextField(
controller: _controller,
autofocus: true,
style: TextStyle(fontSize: 18,),
)
),
Container(
height: 65,
width: double.infinity,
margin: EdgeInsets.only(top: 5,),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('EDIT'),
onPressed: () {
_editToDoItem(_controller.text, index); // error on index, Undefined name 'index'
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
],
),
),
);
});
}
full main.dart file
class ToDoElement {
String task;
final DateTime timeOfCreation;
ToDoElement(this.task, this.timeOfCreation);
}
void main() => runApp(MaterialApp(home: MyApp()));
class MyApp extends StatefulWidget {
#override
createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
List<ToDoElement> _toDoItems = [];
TextEditingController _controller = TextEditingController();
void _addToDoItem(String task) {
if(task.isNotEmpty) {
setState(() {
_toDoItems.add(ToDoElement(task, DateTime.now()));
});
}
}
void _editToDoItem(String newText, int index) {
setState(() {
_toDoItems[index].task = newText;
});
}
void _removeTodoItem(int index) {
setState(() => _toDoItems.removeAt(index));
}
_editDialog(BuildContext context) {
return showDialog(context: context, builder: (context) {
return Dialog(
backgroundColor: Colors.transparent,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20.0)),
),
padding: EdgeInsets.all(20),
height: 180,
width: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 60,
child: TextField(
controller: _controller,
autofocus: true,
/*onSubmitted: (val) {
_addToDoItem(val);
_controller.clear();
},*/
style: TextStyle(fontSize: 18,),
decoration: InputDecoration(
hintText: 'Add a task here...',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
),
)
),
Container(
height: 65,
width: double.infinity,
margin: EdgeInsets.only(top: 5,),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('EDIT', style: TextStyle(fontSize: 18)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
onPressed: () {
_editToDoItem(_controller.text, index);
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
],
),
),
);
});
}
Widget _buildToDoItem(String toDoText, int index) {
return SizedBox(
child: Container(
height: 58,
margin: EdgeInsets.only(left: 22.0, right: 22.0, bottom: 12,),
decoration: BoxDecoration(
border: Border.all(width: 1.5, color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(18)),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children:[
Expanded(
child: ListTile(
title: Text(
toDoText,
style: TextStyle(fontSize: 18),
),
onTap: () => null,
),
),
FlatButton(
child: Text('Edit', style: TextStyle(color: Colors.red, fontSize: 16.5),),
onPressed: () => _editDialog(context),
),
FlatButton(
child: Text('Delete', style: TextStyle(color: Colors.red, fontSize: 16.5),),
onPressed: () => _removeTodoItem(index),
),
],
),
),
);
}
int compareElement(ToDoElement a, ToDoElement b) =>
a.timeOfCreation.isAfter(b.timeOfCreation) ? -1 : 1;
Widget _buildToDoList() {
_toDoItems.sort(compareElement);
return Expanded(
child: ListView.builder(
itemCount: _toDoItems.length,
itemBuilder: (context, index) {
if (index < _toDoItems.length) {
return _buildToDoItem(_toDoItems[index].task, index);
}
},
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(50),
child: AppBar(
centerTitle: true,
backgroundColor: Colors.red,
title: Text('To Do List', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold,),),
)
),
backgroundColor: Colors.white,
body: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
height: 60,
margin: EdgeInsets.all(22),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 10,
child: Container(
height: double.infinity,
child: TextField(
controller: _controller,
autofocus: true,
onSubmitted: (val) {
_addToDoItem(val);
_controller.clear();
},
style: TextStyle(fontSize: 18,),
decoration: InputDecoration(
hintText: 'Add a task here...',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
),
),
),
),
Expanded(
flex: 4,
child: Container(
height: double.infinity,
margin: EdgeInsets.only(left: 12),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('ADD', style: TextStyle(fontSize: 18)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
onPressed: () {
_addToDoItem(_controller.text);
_controller.clear();
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
),
],
),
),
_buildToDoList()
]
),
),
);
}
}
If you have any questions please let me know in the comments;)
You can copy paste run full code below
You can provide index to _editDialog then _editToDoItem can get index
code snippet
_editDialog(BuildContext context, int index)
...
FlatButton(
child: Text(
'Edit',
style: TextStyle(color: Colors.red, fontSize: 16.5),
),
onPressed: () => _editDialog(context, index),
),
working demo
full code
import 'package:flutter/material.dart';
class ToDoElement {
String task;
final DateTime timeOfCreation;
ToDoElement(this.task, this.timeOfCreation);
}
void main() => runApp(MaterialApp(home: MyApp()));
class MyApp extends StatefulWidget {
#override
createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
List<ToDoElement> _toDoItems = [];
TextEditingController _controller = TextEditingController();
TextEditingController _controller1 = TextEditingController();
void _addToDoItem(String task) {
if (task.isNotEmpty) {
setState(() {
_toDoItems.add(ToDoElement(task, DateTime.now()));
});
}
}
void _editToDoItem(String newText, int index) {
setState(() {
_toDoItems[index].task = newText;
});
}
void _removeTodoItem(int index) {
setState(() => _toDoItems.removeAt(index));
}
_editDialog(BuildContext context, int index) {
return showDialog(
context: context,
builder: (context) {
return Dialog(
backgroundColor: Colors.transparent,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(20.0)),
),
padding: EdgeInsets.all(20),
height: 180,
width: 100,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: 60,
child: TextField(
controller: _controller,
autofocus: true,
/*onSubmitted: (val) {
_addToDoItem(val);
_controller.clear();
},*/
style: TextStyle(
fontSize: 18,
),
decoration: InputDecoration(
hintText: 'Add a task here...',
enabledBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
focusedBorder: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
),
)),
Container(
height: 65,
width: double.infinity,
margin: EdgeInsets.only(
top: 5,
),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('EDIT', style: TextStyle(fontSize: 18)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
onPressed: () {
_editToDoItem(_controller.text, index);
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
],
),
),
);
});
}
Widget _buildToDoItem(String toDoText, int index) {
return SizedBox(
child: Container(
height: 58,
margin: EdgeInsets.only(
left: 22.0,
right: 22.0,
bottom: 12,
),
decoration: BoxDecoration(
border: Border.all(width: 1.5, color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(18)),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: ListTile(
title: Text(
toDoText,
style: TextStyle(fontSize: 18),
),
onTap: () => null,
),
),
FlatButton(
child: Text(
'Edit',
style: TextStyle(color: Colors.red, fontSize: 16.5),
),
onPressed: () => _editDialog(context, index),
),
FlatButton(
child: Text(
'Delete',
style: TextStyle(color: Colors.red, fontSize: 16.5),
),
onPressed: () => _removeTodoItem(index),
),
],
),
),
);
}
int compareElement(ToDoElement a, ToDoElement b) =>
a.timeOfCreation.isAfter(b.timeOfCreation) ? -1 : 1;
Widget _buildToDoList() {
_toDoItems.sort(compareElement);
return Expanded(
child: ListView.builder(
itemCount: _toDoItems.length,
itemBuilder: (context, index) {
if (index < _toDoItems.length) {
return _buildToDoItem(_toDoItems[index].task, index);
}
},
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(50),
child: AppBar(
centerTitle: true,
backgroundColor: Colors.red,
title: Text(
'To Do List',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
),
),
)),
backgroundColor: Colors.white,
body: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
Container(
height: 60,
margin: EdgeInsets.all(22),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 10,
child: Container(
height: double.infinity,
child: TextField(
controller: _controller1,
autofocus: true,
onSubmitted: (val) {
_addToDoItem(val);
_controller1.clear();
},
style: TextStyle(
fontSize: 18,
),
decoration: InputDecoration(
hintText: 'Add a task here...',
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(12.0)),
borderSide: BorderSide(color: Colors.red, width: 2),
),
),
),
),
),
Expanded(
flex: 4,
child: Container(
height: double.infinity,
margin: EdgeInsets.only(left: 12),
child: RaisedButton(
textColor: Colors.white,
color: Colors.red,
child: Text('ADD', style: TextStyle(fontSize: 18)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)),
),
onPressed: () {
_addToDoItem(_controller1.text);
_controller1.clear();
FocusScope.of(context).requestFocus(FocusNode());
},
),
),
),
],
),
),
_buildToDoList()
]),
),
);
}
}