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

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

Related

How to make container fixed. the container wont resize after clicking the widgets inside it . Flutter

I am having trouble with my design as i want this container as a background for my dropdowns and textformfield. but its changing its size once i click on description or dates.
Please help how to make it fixed. i have attached some screenshots also of before and after clicking the formfield.
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20.0),
border: Border.all(
// color: Colors.black,
style: BorderStyle.solid,
width: 1.0),
),
// color: Colors.white,
padding: const EdgeInsets.all(32.5),
constraints: const BoxConstraints(
minWidth: 0, maxWidth: 350, minHeight: 0, maxHeight: 440),
child: Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Container(
height: 52,
width: 270,
padding: const EdgeInsets.symmetric(horizontal: 5.0),
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(20.0),
border: Border.all(
// color: Colors.black,
style: BorderStyle.solid,
width: 1.0),
),
child: DropdownButtonHideUnderline(
child: DropdownButton(
hint: const Text('Select Chapter'),
items: chapteritemlist.map((item) {
return DropdownMenuItem(
value: item['chapterId'].toString(),
child: Text(item['chapter'].toString()),
);
}).toList(),
onChanged: (newVal) {
setState(() {
dropdownchapterdisplay = newVal;
});
chaptid = newVal;
print(chaptid);
getAllMember();
},
value: dropdownchapterdisplay,
),
),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Container(
height: 52,
width: 270,
padding: EdgeInsets.symmetric(horizontal: 0),
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(20.0),
border: Border.all(
// color: Colors.black,
style: BorderStyle.solid,
width: 1.0),
),
child: DropdownButtonHideUnderline(
child: DropdownButton(
hint: const Text('Select Member'),
items: memberitemlist.map((item) {
return DropdownMenuItem(
value: item['id'].toString(),
child: Text(
item['name'].toString(),
style: const TextStyle(
fontSize: 9,
),
),
);
}).toList(),
onChanged: (newVal) {
setState(() {
dropdownmemberdisplay = newVal;
});
memberid = newVal;
},
value: dropdownmemberdisplay,
),
),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox(
height: 48,
width: 270,
child: TextFormField(
// The validator receives the text that the user has entered.
// textAlign: TextAlign.center,
controller: description,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
),
hintText: "Description",
filled: true,
fillColor: Colors.grey[200],
),
),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox(
height: 88,
width: 270,
child: DateTimeFormField(
decoration: InputDecoration(
hintStyle: const TextStyle(color: Colors.black),
errorStyle: const TextStyle(color: Colors.redAccent),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
),
hintText: 'MM DD, YYYY',
filled: true,
fillColor: Colors.grey[200],
suffixIcon: const Icon(Icons.event_note),
labelText: 'Select Date',
),
mode: DateTimeFieldPickerMode.date,
autovalidateMode: AutovalidateMode.always,
validator: (e) => (e?.day ?? 0) == 1
? 'Please not the first day'
: null,
onDateSelected: (DateTime value) {},
),
),
),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: Row(children: <Widget>[
Padding(
padding: const EdgeInsets.all(6.0),
child: Align(
alignment: Alignment.bottomLeft,
child: ElevatedButton(
onPressed: () {
saveRequestModel = SaveClass();
saveRequestModel.Description = description.text;
saveRequestModel.UserName = global_Email;
saveRequestModel.Id = 0;
saveRequestModel.toFId = 0;
saveRequestModel.ToSelf = 0;
saveRequestModel.TranType = 0;
saveRequestModel.ToId = 6;
saveRequestModel.MeetingDate = '2022-10-02';
print(saveRequestModel.ToId);
SaveService saveService = SaveService();
saveService.save(saveRequestModel).then((value) {
print("data saved");
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.deepPurple[900],
textStyle: const TextStyle(
color: Colors.white,
fontSize: 25,
fontStyle: FontStyle.normal),
),
// color: Colors.deepPurple[900],
// textColor: Colors.white,
// elevation: 5,
child: const Text('Save',
style: TextStyle(fontSize: 20)),
),
),
),
Padding(
padding: const EdgeInsets.only(left: 20),
child: Align(
alignment: Alignment.bottomRight,
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.deepPurple[900],
textStyle: const TextStyle(
color: Colors.white,
fontSize: 25,
fontStyle: FontStyle.normal),
),
// color: Colors.deepPurple[900],
// textColor: Colors.white,
// elevation: 5,
child: const Text('Check Report',
style: TextStyle(fontSize: 20)),
),
))
]),
),
],
)),
Here is the full code.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:date_field/date_field.dart';
//import 'package:saarthi/api/saarthi_meeting/chapter_api.dart';
import 'package:saarthi/api/saarthi_meeting/sarthi_services.dart';
import 'package:http/http.dart' as http;
import 'package:saarthi/api/saarthi_meeting/save_button.dart';
import 'package:saarthi/model/saarthi_meeting/saarthi_model.dart';
import 'package:saarthi/model/saarthi_meeting/save_model.dart';
import 'package:saarthi/variables.dart';
void main() {
runApp(Saarthi_Meeting());
}
class Saarthi_Meeting extends StatelessWidget {
Saarthi_Meeting({Key? key}) : super(key: key);
String value = "";
String url = '';
#override
Widget build(BuildContext context) {
return const MaterialApp(
home: datadisplay(),
debugShowCheckedModeBanner: false,
);
}
}
class datadisplay extends StatefulWidget {
const datadisplay({Key? key}) : super(key: key);
#override
State<datadisplay> createState() => _datadisplayState();
}
class _datadisplayState extends State<datadisplay> {
final SaarthiService _fetchdata = SaarthiService();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.deepPurple[900],
appBar: AppBar(
title: Image.asset('assets/images/CG.png', width: 200),
backgroundColor: Colors.deepPurple[900],
elevation: 13,
actions: [
IconButton(
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => smdesign()));
},
icon: const Icon(Icons.add),
)
],
),
body: Container(
padding: const EdgeInsets.all(20),
child: FutureBuilder<List<Saarthidata>>(
future: _fetchdata.smdata(),
builder: (context, snapshot) {
var data = snapshot.data;
return ListView.builder(
itemCount: data?.length,
itemBuilder: (context, index) {
if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator());
}
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: ListTile(
onTap: () {
if (data?[index].id != null) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => smdesign(),
),
);
}
},
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'On Date - ${data?[index].date}',
style: const TextStyle(
fontSize: 10,
fontWeight: FontWeight.w600),
),
const SizedBox(height: 10),
Text(
'From User - ${data?[index].fromName}',
style: const TextStyle(
color: Colors.black,
fontSize: 14,
fontWeight: FontWeight.w400,
),
),
const SizedBox(height: 10),
Text(
'To User - ${data?[index].toName}',
style: const TextStyle(
color: Colors.black,
fontSize: 14,
fontWeight: FontWeight.w400,
),
),
const SizedBox(height: 10),
]),
),
),
);
});
}),
),
);
}
}
class smdesign extends StatefulWidget {
smdesign({Key? key}) : super(key: key);
#override
State<smdesign> createState() => _smdesignState();
}
class _smdesignState extends State<smdesign> {
String? dropdownvalue = "Self";
String chaptervalue = "One";
bool isVisible = false;
//---------------------variable----------------------------------------------------API
List chapteritemlist = [];
var dropdownchapterdisplay;
//---------------------variable----------------------------------------------------API
List memberitemlist = [];
var dropdownmemberdisplay;
//------------------------------api dropdown 3 ---------------------------------
//--------------------------------------------------------------------------API
//----------------------------------save-------------------save--------------------------
late SaveClass saveRequestModel;
var description = TextEditingController();
//----------------------------------save-------------------save--------------------------
#override
void initState() {
super.initState();
getAllChapter();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.deepPurple[900],
appBar: AppBar(
title: Image.asset('assets/images/CG.png', width: 200),
backgroundColor: Colors.deepPurple[900],
elevation: 13,
),
body: Center(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20.0),
border: Border.all(
// color: Colors.black,
style: BorderStyle.solid,
width: 1.0),
),
// color: Colors.white,
padding: const EdgeInsets.all(32.5),
constraints: const BoxConstraints(
minWidth: 0, maxWidth: 350, minHeight: 0, maxHeight: 440),
child: Column(
children: <Widget>[
Expanded(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Container(
height: 52,
width: 270,
padding: const EdgeInsets.symmetric(horizontal: 5.0),
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(20.0),
border: Border.all(
// color: Colors.black,
style: BorderStyle.solid,
width: 1.0),
),
child: DropdownButtonHideUnderline(
child: DropdownButton(
hint: const Text('Select Chapter'),
items: chapteritemlist.map((item) {
return DropdownMenuItem(
value: item['chapterId'].toString(),
child: Text(item['chapter'].toString()),
);
}).toList(),
onChanged: (newVal) {
setState(() {
dropdownchapterdisplay = newVal;
});
chaptid = newVal;
print(chaptid);
getAllMember();
},
value: dropdownchapterdisplay,
),
),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: Container(
height: 52,
width: 270,
padding: EdgeInsets.symmetric(horizontal: 0),
decoration: BoxDecoration(
color: Colors.grey[200],
borderRadius: BorderRadius.circular(20.0),
border: Border.all(
// color: Colors.black,
style: BorderStyle.solid,
width: 1.0),
),
child: DropdownButtonHideUnderline(
child: DropdownButton(
hint: const Text('Select Member'),
items: memberitemlist.map((item) {
return DropdownMenuItem(
value: item['id'].toString(),
child: Text(
item['name'].toString(),
style: const TextStyle(
fontSize: 9,
),
),
);
}).toList(),
onChanged: (newVal) {
setState(() {
dropdownmemberdisplay = newVal;
});
memberid = newVal;
},
value: dropdownmemberdisplay,
),
),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox(
height: 48,
width: 270,
child: TextFormField(
// The validator receives the text that the user has entered.
// textAlign: TextAlign.center,
controller: description,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
),
hintText: "Description",
filled: true,
fillColor: Colors.grey[200],
),
),
),
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(5.0),
child: SizedBox(
height: 88,
width: 270,
child: DateTimeFormField(
decoration: InputDecoration(
hintStyle: const TextStyle(color: Colors.black),
errorStyle: const TextStyle(color: Colors.redAccent),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20),
),
hintText: 'MM DD, YYYY',
filled: true,
fillColor: Colors.grey[200],
suffixIcon: const Icon(Icons.event_note),
labelText: 'Select Date',
),
mode: DateTimeFieldPickerMode.date,
autovalidateMode: AutovalidateMode.always,
validator: (e) => (e?.day ?? 0) == 1
? 'Please not the first day'
: null,
onDateSelected: (DateTime value) {},
),
),
),
),
Padding(
padding: const EdgeInsets.all(2.0),
child: Row(children: <Widget>[
Padding(
padding: const EdgeInsets.all(6.0),
child: Align(
alignment: Alignment.bottomLeft,
child: ElevatedButton(
onPressed: () {
saveRequestModel = SaveClass();
saveRequestModel.Description = description.text;
saveRequestModel.UserName = global_Email;
saveRequestModel.Id = 0;
saveRequestModel.toFId = 0;
saveRequestModel.ToSelf = 0;
saveRequestModel.TranType = 0;
saveRequestModel.ToId = 6;
saveRequestModel.MeetingDate = '2022-10-02';
print(saveRequestModel.ToId);
SaveService saveService = SaveService();
saveService.save(saveRequestModel).then((value) {
print("data saved");
});
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.deepPurple[900],
textStyle: const TextStyle(
color: Colors.white,
fontSize: 25,
fontStyle: FontStyle.normal),
),
// color: Colors.deepPurple[900],
// textColor: Colors.white,
// elevation: 5,
child: const Text('Save',
style: TextStyle(fontSize: 20)),
),
),
),
Padding(
padding: const EdgeInsets.only(left: 20),
child: Align(
alignment: Alignment.bottomRight,
child: ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.deepPurple[900],
textStyle: const TextStyle(
color: Colors.white,
font size: 25,
fontStyle: FontStyle.normal),
),
// color: Colors.deepPurple[900],
// textColor: Colors.white,
// elevation: 5,
child: const Text('Check Report',
style: TextStyle(fontSize: 20)),
),
))
]),
),
],
)),
),
);
}
}
Before Image -This is before clicking anything. The design
After Image -when I click on the description form field it shows like this.

Firebase sign in and sign up with email and password for flutter issue

I have connect my flutter app with firebase. then, I implement Signin and Signup(new user creation)screens with email and password . sign in is works fine and its redirect to home page. and the actual problem is with the signup page route, it cannot redirect into homepage but the values are stored in to the firebase !! anyone give me a solution????
login page
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:food_delivery_app/screens/signup/signup_screen.dart';
import '../../config/constants.dart';
import '../../config/theme.dart';
import '../../utils/helper.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({Key? key}) : super(key: key);
#override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final emailController = TextEditingController();
final passwordController = TextEditingController();
#override
void dispose() {
emailController.dispose();
passwordController.dispose();
super.dispose();
}
bool isLoading = false;
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: [
Image.asset(
Helper.getAssetName("bg-home.jpg", "virtual"),
fit: BoxFit.contain,
),
htspace40,
SizedBox(
child: Text(
'UAE\' Most Reliable Food \nDelivery and Dining App',
style: AppTextStyle.boldSpaceBlack(),
textAlign: TextAlign.center,
)),
htspace20,
Container(
padding: const EdgeInsets.all(20),
child: Column(
children: [
Text(
'Log In',
style: AppTextStyle.light20(),
textAlign: TextAlign.center,
),
htspace20,
Material(
elevation: 12,
shadowColor: AppColors.shadowTxt,
child: SizedBox(
height: 50.0,
width: 320,
child: TextField(
controller: emailController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(9),
),
label: const Text(
'Email',
style: TextStyle(color: AppColors.txt),
),
),
),
),
),
htspace20,
Material(
elevation: 12,
shadowColor: AppColors.shadowTxt,
child: SizedBox(
height: 50.0,
width: 320,
child: TextField(
controller: passwordController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(9),
),
label: const Text(
'Password',
style: TextStyle(color: AppColors.txt),
),
),
),
),
),
SizedBox(
width: 320,
child: Row(
children: [
const Text('Don\'t have an account?'),
TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const SignUpScreen()),
);
},
child: const Text('Sign up'),
)
],
),
),
SizedBox(
width: 284.0,
height: 40,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20), // <-- Radius
),
),
child: isLoading
? const SizedBox(
height: 30,
width: 30,
child: CircularProgressIndicator(
strokeWidth: 3, color: Colors.white),
)
: const Text('Sign in'),
onPressed: () {
setState(() {
isLoading = true;
});
signIn();
Future.delayed(const Duration(seconds: 3), () {
setState(() {
if (emailController.text != " " ||
passwordController.text != " ") {
isLoading = false;
} else {
isLoading = true;
}
});
});
}),
)
],
),
),
Text(
'or',
style: AppTextStyle.regular14(),
textAlign: TextAlign.center,
),
htspace20,
Padding(
padding: const EdgeInsets.only(left: 50.0, right: 50.0),
child: Row(
children: [
Container(
decoration: BoxDecoration(
border: Border.all(color: AppColors.txt, width: 1.0),
shape: BoxShape.circle,
),
child: IconButton(
onPressed: () {},
icon: Image.asset(
Helper.getAssetName("google.png", "virtual"),
),
),
),
const Spacer(),
Container(
decoration: BoxDecoration(
border: Border.all(color: AppColors.txt, width: 1.0),
shape: BoxShape.circle,
),
child: IconButton(
onPressed: () {},
icon: Image.asset(
Helper.getAssetName("apple.png", "virtual"),
),
),
),
const Spacer(),
Container(
decoration: BoxDecoration(
border: Border.all(color: AppColors.txt, width: 1.0),
shape: BoxShape.circle,
),
child: IconButton(
onPressed: () {},
icon: const Icon(
Icons.more_horiz_rounded,
size: 30,
color: Colors.black,
),
),
),
],
),
),
Column(
children: [
const SizedBox(
height: 15,
),
Stack(children: [
const Align(
alignment: AlignmentDirectional.center,
child: Text(
'By Continuing, you agree to our',
),
),
Padding(
padding: const EdgeInsets.only(left: 60.0, right: 0.0),
child: Row(
children: [
TextButton(
onPressed: () {},
child: Text(
'Terms of Service',
style: AppTextStyle.regular10(),
),
),
TextButton(
onPressed: () {},
child: Text(
' Privacy Policy',
style: AppTextStyle.regular10(),
),
),
TextButton(
onPressed: () {},
child: Text(
'Content Policies',
style: AppTextStyle.regular10(),
),
),
],
),
)
]),
],
)
],
),
);
}
Future signIn() async {
try {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: emailController.text.trim(),
password: passwordController.text.trim(),
);
} catch (e) {
debugPrint('Email or Password Incorrect');
}
}
}
signup page
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:food_delivery_app/screens/login/login_screen.dart';
import '../../config/constants.dart';
import '../../config/theme.dart';
import '../../utils/helper.dart';
class SignUpScreen extends StatefulWidget {
const SignUpScreen({Key? key}) : super(key: key);
#override
State<SignUpScreen> createState() => _SignUpScreenState();
}
class _SignUpScreenState extends State<SignUpScreen> {
final emailController = TextEditingController();
final passwordController = TextEditingController();
#override
void dispose() {
emailController.dispose();
passwordController.dispose();
super.dispose();
}
bool isLoading = false;
#override
Widget build(BuildContext context) {
return Scaffold(
body: ListView(
children: [
Image.asset(
Helper.getAssetName("bg-home.jpg", "virtual"),
fit: BoxFit.contain,
),
htspace40,
SizedBox(
child: Text(
'UAE\' Most Reliable Food \nDelivery and Dining App',
style: AppTextStyle.boldSpaceBlack(),
textAlign: TextAlign.center,
)),
htspace20,
Container(
padding: const EdgeInsets.all(20),
child: Column(
children: [
Text(
'Sign Up',
style: AppTextStyle.light20(),
textAlign: TextAlign.center,
),
htspace20,
Material(
elevation: 12,
shadowColor: AppColors.shadowTxt,
child: SizedBox(
height: 50.0,
width: 320,
child: TextField(
controller: emailController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(9),
),
label: const Text(
'Email',
style: TextStyle(color: AppColors.txt),
),
),
),
),
),
htspace20,
Material(
elevation: 12,
shadowColor: AppColors.shadowTxt,
child: SizedBox(
height: 50.0,
width: 320,
child: TextField(
controller: passwordController,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(9),
),
label: const Text(
'Password',
style: TextStyle(color: AppColors.txt),
),
),
),
),
),
SizedBox(
width: 320,
child: Row(
children: [
const Text('Already have an account?'),
TextButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const LoginScreen()),
);
},
child: Container(
margin: const EdgeInsets.only(right: 25),
child: const Text('login'),
))
],
),
),
SizedBox(
width: 284.0,
height: 40,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20), // <-- Radius
),
),
child: isLoading
? const SizedBox(
height: 30,
width: 30,
child: CircularProgressIndicator(
strokeWidth: 3, color: Colors.white),
)
: const Text('Sign up'),
onPressed: () {
// setState(() {
// isLoading = true;
// });
signUp();
// Future.delayed(const Duration(seconds: 3), () {
// setState(() {
// if (emailController.text != " " ||
// passwordController.text != " ") {
// isLoading = false;
// } else {
// isLoading = true;
// }
// });
// });
}),
)
],
),
),
Text(
'or',
style: AppTextStyle.regular14(),
textAlign: TextAlign.center,
),
htspace20,
Padding(
padding: const EdgeInsets.only(left: 50.0, right: 50.0),
child: Row(
children: [
Container(
decoration: BoxDecoration(
border: Border.all(color: AppColors.txt, width: 1.0),
shape: BoxShape.circle,
),
child: IconButton(
onPressed: () {},
icon: Image.asset(
Helper.getAssetName("google.png", "virtual"),
),
),
),
const Spacer(),
Container(
decoration: BoxDecoration(
border: Border.all(color: AppColors.txt, width: 1.0),
shape: BoxShape.circle,
),
child: IconButton(
onPressed: () {},
icon: Image.asset(
Helper.getAssetName("apple.png", "virtual"),
),
),
),
const Spacer(),
Container(
decoration: BoxDecoration(
border: Border.all(color: AppColors.txt, width: 1.0),
shape: BoxShape.circle,
),
child: IconButton(
onPressed: () {},
icon: const Icon(
Icons.more_horiz_rounded,
size: 30,
color: Colors.black,
),
),
),
],
),
),
Column(
children: [
const SizedBox(
height: 15,
),
Stack(children: [
const Align(
alignment: AlignmentDirectional.center,
child: Text(
'By Continuing, you agree to our',
),
),
Padding(
padding: const EdgeInsets.only(left: 60.0, right: 0.0),
child: Row(
children: [
TextButton(
onPressed: () {},
child: Text(
'Terms of Service',
style: AppTextStyle.regular10(),
),
),
TextButton(
onPressed: () {},
child: Text(
' Privacy Policy',
style: AppTextStyle.regular10(),
),
),
TextButton(
onPressed: () {},
child: Text(
'Content Policies',
style: AppTextStyle.regular10(),
),
),
],
),
)
]),
],
)
],
),
);
}
Future signUp() async {
try {
await FirebaseAuth.instance.createUserWithEmailAndPassword(
email: emailController.text.trim(),
password: passwordController.text.trim(),
);
} catch (e) {
debugPrint('Email or Password Incorrect');
}
}
}
home page
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:food_delivery_app/screens/signup/signup_screen.dart';
import '../../config/theme.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const SignUpScreen();
}
return Scaffold(
appBar: AppBar(
title: Text(
'Home',
style: AppTextStyle.bold(),
),
actions: [
IconButton(
onPressed: () => FirebaseAuth.instance.signOut(),
icon: const Icon(Icons.logout),
splashRadius: 20,
)
],
),
body: const Center(
child: Text('Homeeee'),
),
);
});
}
}

The method 'userLogin' isn't defined for the type 'BottomSheet'

I have this error in the onPressed :() function of the login: The method 'userLogin' is not defined for the type 'BottomSheet'.
Could anyone help me solve? Thank you.
CustomButton(
label: "LOGIN",
primaryColor: Theme.of(context).primaryColor,
secondaryColor: Colors.white,
onPressed: () => {
// Validate returns true if the form is valid, or false otherwise.
if (_formKey.currentState.validate()) {
userLogin()}
},
),
Here is the complete code:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:login_ui/home2.dart';
import 'clipper.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
TextEditingController _emailController,
_passwordController,
_nameController = TextEditingController();
//
bool _visible = false;
Future userLogin() async {
//Login API URL
//use your local IP address instead of localhost or use Web API
String url = "https://www.toptradeitaly.com/login_api/user_login.php";
// Showing LinearProgressIndicator.
setState(() {
_visible = true;
});
// Getting username and password from Controller
var data = {
'username': _emailController.text,
'password': _passwordController.text,
};
//Starting Web API Call.
var response = await http.post(url, body: json.encode(data));
if (response.statusCode == 200) {
//Server response into variable
print(response.body);
var msg = jsonDecode(response.body);
//Check Login Status
if (msg['loginStatus'] == true) {
setState(() {
//hide progress indicator
_visible = false;
});
// Navigate to Home Screen
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
HomePage(uname: msg['userInfo']['NAME'])));
} else {
setState(() {
//hide progress indicator
_visible = false;
//Show Error Message Dialog
showMessage(msg["message"]);
});
}
} else {
setState(() {
//hide progress indicator
_visible = false;
//Show Error Message Dialog
showMessage("Error during connecting to Server.");
});
}
}
Future<dynamic> showMessage(String _msg) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: new Text(_msg),
actions: <Widget>[
TextButton(
child: new Text("OK"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
//
#override
Widget build(BuildContext context) {
//GO logo widget
Widget logo() {
return Padding(
padding:
EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.15),
child: Container(
width: MediaQuery.of(context).size.width,
height: 220,
child: Stack(
children: <Widget>[
Positioned(
child: Container(
child: Align(
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.white),
width: 150,
height: 150,
),
),
height: 154,
)),
Positioned(
child: Container(
height: 154,
child: Align(
child: Text(
"GO",
style: TextStyle(
fontSize: 120,
fontWeight: FontWeight.bold,
color: Theme.of(context).primaryColor,
),
),
)),
),
Positioned(
width: MediaQuery.of(context).size.width * 0.15,
height: MediaQuery.of(context).size.width * 0.15,
bottom: MediaQuery.of(context).size.height * 0.046,
right: MediaQuery.of(context).size.width * 0.22,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.white),
),
),
Positioned(
width: MediaQuery.of(context).size.width * 0.08,
height: MediaQuery.of(context).size.width * 0.08,
bottom: 0,
right: MediaQuery.of(context).size.width * 0.32,
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle, color: Colors.white),
),
),
],
),
),
);
}
void _loginSheet(context) {
showBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return BottomSheet(
emailController: _emailController,
passwordController: _passwordController,
);
},
);
}
void _registerSheet(context) {
showBottomSheet<void>(
context: context,
builder: (BuildContext context) {
return BottomSheet(
emailController: _emailController,
passwordController: _passwordController,
nameController: _nameController,
);
},
);
}
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Theme.of(context).primaryColor,
body: Builder(builder: (context) {
return Column(
children: <Widget>[
logo(),
Padding(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
CustomButton(
label: "LOGIN",
primaryColor: Colors.white,
secondaryColor: Theme.of(context).primaryColor,
onPressed: () => _loginSheet(context),
),
SizedBox(height: 20),
CustomButton(
label: "REGISTER",
primaryColor: Theme.of(context).primaryColor,
secondaryColor: Colors.white,
onPressed: () => _registerSheet(context),
),
],
),
padding: EdgeInsets.only(top: 80, left: 20, right: 20),
),
Expanded(
child: Align(
child: ClipPath(
child: Container(
color: Colors.white,
height: 300,
),
clipper: BottomWaveClipper(),
),
alignment: Alignment.bottomCenter,
),
)
],
crossAxisAlignment: CrossAxisAlignment.stretch,
);
}),
);
}
}
class CustomButton extends StatelessWidget {
final Color primaryColor;
final Color secondaryColor;
final String label;
final Function() onPressed;
const CustomButton({
Key key,
this.primaryColor,
this.secondaryColor,
#required this.label,
this.onPressed,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return SizedBox(
height: 50,
width: double.infinity,
child: RaisedButton(
highlightElevation: 0.0,
splashColor: secondaryColor,
highlightColor: primaryColor,
elevation: 0.0,
color: primaryColor,
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(30.0),
side: BorderSide(color: Colors.white, width: 3)),
child: Text(
label,
style: TextStyle(
fontWeight: FontWeight.bold, color: secondaryColor, fontSize: 20),
),
onPressed: onPressed,
),
);
}
}
class CustomTextField extends StatelessWidget {
final Icon icon;
final String hint;
final TextEditingController controller;
final bool obsecure;
const CustomTextField({
this.controller,
this.hint,
this.icon,
this.obsecure,
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return TextField(
controller: controller,
obscureText: obsecure ?? false,
style: TextStyle(
fontSize: 20,
),
decoration: InputDecoration(
hintStyle: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
hintText: hint,
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: BorderSide(
color: Theme.of(context).primaryColor,
width: 2,
),
),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: BorderSide(
color: Theme.of(context).primaryColor,
width: 3,
),
),
prefixIcon: Padding(
child: IconTheme(
data: IconThemeData(color: Theme.of(context).primaryColor),
child: icon,
),
padding: EdgeInsets.only(left: 30, right: 10),
)),
);
}
}
//
final _formKey = GlobalKey<FormState>();
//
class BottomSheet extends StatelessWidget {
const BottomSheet({
Key key,
#required TextEditingController emailController,
#required TextEditingController passwordController,
TextEditingController nameController,
}) : _emailController = emailController,
_passwordController = passwordController,
_nameController = nameController,
super(key: key);
final TextEditingController _emailController;
final TextEditingController _passwordController;
final TextEditingController _nameController;
List<Widget> get _registerLogo => [
Positioned(
child: Container(
padding: EdgeInsets.only(bottom: 25, right: 40),
child: Text(
"REGI",
style: TextStyle(
fontSize: 38,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
alignment: Alignment.center,
),
),
Positioned(
child: Align(
child: Container(
padding: EdgeInsets.only(top: 40, left: 28),
width: 130,
child: Text(
"STER",
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
fontSize: 38),
),
),
alignment: Alignment.center,
),
),
];
List<Widget> get _loginLogo => [
Align(
alignment: Alignment.center,
child: Container(
child: Text(
"LOGIN",
style: TextStyle(
fontSize: 42,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
alignment: Alignment.center,
),
),
];
#override
Widget build(BuildContext context) {
return DecoratedBox(
decoration: BoxDecoration(color: Theme.of(context).canvasColor),
child: ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(40.0), topRight: Radius.circular(40.0)),
child: Container(
child: ListView(
children: <Widget>[
Container(
child: Stack(
children: <Widget>[
Positioned(
left: 10,
top: 10,
child: IconButton(
onPressed: () {
Navigator.of(context).pop();
_emailController.clear();
_passwordController.clear();
_nameController?.clear();
},
icon: Icon(
Icons.close,
size: 30.0,
color: Theme.of(context).primaryColor,
),
),
)
],
),
height: 50,
width: 50,
),
//
Form(
key: _formKey,
child:
//
SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(left: 20, right: 20),
child: Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
height: 140,
child: Stack(
children: <Widget>[
Align(
child: Container(
width: 130,
height: 130,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Theme.of(context).primaryColor),
),
alignment: Alignment.center,
),
..._nameController != null
? _registerLogo
: _loginLogo
],
),
),
SizedBox(height: 60),
if (_nameController != null)
CustomTextField(
controller: _nameController,
hint: "NAME",
icon: Icon(Icons.person),
),
SizedBox(height: 20),
CustomTextField(
controller: _emailController,
hint: "EMAIL",
icon: Icon(Icons.email),
),
SizedBox(height: 20),
CustomTextField(
controller: _passwordController,
hint: "PASSWORD",
icon: Icon(Icons.lock),
obsecure: true,
),
SizedBox(height: 20),
if (_nameController != null)
CustomButton(
label: "REGISTER",
primaryColor: Theme.of(context).primaryColor,
secondaryColor: Colors.white,
onPressed: () {},
),
SizedBox(height: 20),
if (_nameController == null)
CustomButton(
label: "LOGIN",
primaryColor: Theme.of(context).primaryColor,
secondaryColor: Colors.white,
onPressed: () => {
// Validate returns true if the form is valid, or false otherwise.
if (_formKey.currentState.validate()) {
userLogin()}
},
),
SizedBox(height: 20),
],
),
),
),),
],
),
height: MediaQuery.of(context).size.height / 1.1,
width: MediaQuery.of(context).size.width,
color: Colors.white,
),
),
);
}
}

Update Text() based on user input in a TextFormField() within a form, perform a calculation and display results in another TextFormField()

I'm still new in Flutter, I'm trying to Update Text() based on user input in a TextFormField() within a form, perform two calculations and display results in other TextFormField() then POST the data to an API on pressing the Upload Button. I have tried using setState(){} as below but it's not working out.
'serviceFee' is supposed to be 2% of the 'amount' entered by the user then 'takeHome' is supposed to be 'amount' minus 'serviceFee'. Below is my code...
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:keilvog/Screens/6kg_cylinder_screen.dart';
import 'package:keilvog/Widget/edit_image.dart';
import 'package:keilvog/Widget/header.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:http/http.dart' as http;
import 'package:keilvog/Widget/validators.dart';
import 'package:shared_preferences/shared_preferences.dart';
class SellDetails extends StatefulWidget {
const SellDetails({Key? key}) : super(key: key);
#override
State<SellDetails> createState() => _SellDetailsState();
}
class _SellDetailsState extends State<SellDetails> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final brandController = TextEditingController();
final capacityController = TextEditingController();
final amountController = TextEditingController();
final serviceFeeController = TextEditingController();
final takeHomeController = TextEditingController();
File? image;
bool isLoading = false;
double _serviceFee = 0;
// ignore: unused_field
double _takeHome = 0;
double amount = 0;
Future UploadData({
String? brand,
String? capacity,
double? amount,
double? serviceFee,
double? takeHome,
File? image
}) async
{
final SharedPreferences preferences = await SharedPreferences.getInstance();
final String? myJWT = preferences.getString('jwt');
Map<String, dynamic> token = jsonDecode(myJWT!);
final myResponse = await http.post(
Uri.parse('https://kelivog.com/sell/cylinder'),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',
'Authorization': '$token',
},
body: jsonEncode(
{
'brand': brand,
'capacity': capacity,
'amount': amount,
'serviceFee': serviceFee,
'takeHome': takeHome,
'image':'data:image/png;base64,' + base64Encode(image!.readAsBytesSync()),
}),
);
return myResponse.statusCode;
}
#override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("images/background.jpg"), fit: BoxFit.cover)),
child: Scaffold(
// body: SingleChildScrollView(
body: SingleChildScrollView(
child: Column(
children: [
header(),
SizedBox(height: 20.h),
const EditImage(),
SizedBox(height: 30.h),
Container(
width: 350.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(15.r)),
image: const DecorationImage(
image: AssetImage("images/background.jpg"),
fit: BoxFit.fitWidth,
alignment: Alignment.topCenter,
),
boxShadow: const [
BoxShadow(color: Colors.grey, spreadRadius: 2),
],
),
child: Column(
children: [
Padding(
padding: EdgeInsets.symmetric(
vertical: 12.h, horizontal: 16.w),
child: Row(
children: [
Expanded(
child: Text("BRAND",
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
)),
),
SizedBox(width: 1.w),
Expanded(
child: Container(
width: 90.w,
height: 40.h,
decoration: BoxDecoration(
color: Colors.yellow[600],
borderRadius: BorderRadius.circular(15)),
child: Center(
child: TextFormField(
//textAlignVertical: TextAlignVertical.center,
validator: brandValidator,
controller: brandController,
showCursor: false,
style: const TextStyle(
fontSize: 20.0,
height: 2.0,
color: Colors.black,
),
decoration: const InputDecoration(
contentPadding: EdgeInsets.only(
top: 1.0, bottom: 100.0, left: 8.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(15.0)),
),
),
),
),
),
),
],
),
),
//const Divider(indent: 15, endIndent: 15, thickness: 2),
Padding(
padding: EdgeInsets.symmetric(
vertical: 12.h, horizontal: 16.w),
child: Row(
children: [
Expanded(
child: Text("CAPACITY",
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
)),
),
SizedBox(width: 1.w),
Expanded(
child: Container(
width: 90.w,
height: 40.h,
decoration: BoxDecoration(
color: Colors.yellow[600],
borderRadius: BorderRadius.circular(15)),
child: Center(
child: TextFormField(
validator: capacityValidator,
controller: capacityController,
showCursor: false,
style: const TextStyle(
fontSize: 20.0,
height: 2.0,
color: Colors.black,
),
decoration: const InputDecoration(
contentPadding: EdgeInsets.only(
top: 1.0, bottom: 100.0, left: 8.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(15.0)),
),
),
),
),
),
),
],
),
),
Padding(
padding: EdgeInsets.symmetric(
vertical: 12.h, horizontal: 16.w),
child: Row(
children: [
Expanded(
child: Text("AMOUNT",
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
)),
),
SizedBox(width: 1.w),
Expanded(
child: Container(
width: 90.w,
height: 40.h,
decoration: BoxDecoration(
color: Colors.yellow[600],
borderRadius: BorderRadius.circular(15)),
child: Center(
child: TextFormField(
validator: amountValidator,
controller: amountController,
keyboardType: TextInputType.number,
showCursor: false,
style: const TextStyle(
fontSize: 20.0,
height: 2.0,
color: Colors.black,
),
decoration: const InputDecoration(
contentPadding: EdgeInsets.only(
top: 1.0, bottom: 100.0, left: 8.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(15.0)),
),
),
onChanged: (value) {
setState(() {
amount = value as double;
});
},
),
),
),
),
],
),
),
Padding(
padding: EdgeInsets.symmetric(
vertical: 12.h, horizontal: 16.w),
child: Row(
children: [
Expanded(
child: Text("SERVICE FEE",
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
)),
),
SizedBox(width: 1.w),
Expanded(
child: Container(
width: 90.w,
height: 40.h,
decoration: BoxDecoration(
color: Colors.yellow[600],
borderRadius: BorderRadius.circular(15)),
child: Center(
//child: Text(serviceFeeController.text),
child: TextFormField(
onChanged: (value) => setState(() {
_serviceFee = value as double;
}),
// validator: ,
// controller: ,
showCursor: false,
style: const TextStyle(
fontSize: 20.0,
height: 2.0,
color: Colors.black,
),
decoration: const InputDecoration(
contentPadding: EdgeInsets.only(
top: 1.0, bottom: 100.0, left: 8.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(15.0)),
),
),
),
),
),
),
],
),
),
Padding(
padding: EdgeInsets.symmetric(
vertical: 12.h, horizontal: 16.w),
child: Row(
children: [
Expanded(
child: Text("TAKE HOME",
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
)),
),
SizedBox(width: 1.w),
Expanded(
child: Container(
width: 90.w,
height: 40.h,
decoration: BoxDecoration(
color: Colors.yellow[600],
borderRadius: BorderRadius.circular(15)),
child: Center(
//child: Text(serviceFeeController.text),
child: TextFormField(
onChanged: (value) => setState(() {
_takeHome = value as double;
}),
// validator: ,
// controller: ,
showCursor: false,
style: const TextStyle(
fontSize: 20.0,
height: 2.0,
color: Colors.black,
),
decoration: const InputDecoration(
contentPadding: EdgeInsets.only(
top: 1.0, bottom: 100.0, left: 8.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(15.0)),
),
),
),
),
),
),
],
),
),
// rowItem('BRAND'),
// rowItem('CAPACITY'),
// rowItem('AMOUNT'),
// rowItem('SERVICE FEE'),
// rowItem('TAKE HOME'),
],
),
),
SizedBox(height: 40.h),
ElevatedButton(
onPressed: () async {
setState(() {
_serviceFee = (amount * 0.02);
});
setState(() {
_takeHome = amount - _serviceFee;
});
//final FormState? form = _formKey.currentState;
if (_formKey.currentState!.validate()){
if (image != null) {
await UploadData(
image: image,
brand: brandController.text,
capacity: capacityController.text,
amount: amountController.text as double,
serviceFee: serviceFeeController.text as double,
takeHome: takeHomeController.text as double
);
}
else
{
// ignore: avoid_print
print('You have not added an image');
}
if (isLoading) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
const SixCylindersListsScreen(
item: '', id: '', title: '',
)));
} else {
throw Exception('Failed to upload details.');
}
}
},
child: Text(
'UPLOAD',
style: TextStyle(
color: Colors.yellow[600],
fontSize: 22.sp,
fontWeight: FontWeight.w700,
),
),
style: ElevatedButton.styleFrom(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.r),
),
fixedSize: Size(150.w, 50.h),
primary: const Color(0xff261005),
),
),
],
),
),
),
);
}
}
Here a quick example
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp>{
final TextEditingController _controller = TextEditingController();
double? fees;
double? takeHome;
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Column(
children: [
TextFormField(
decoration: const InputDecoration(
labelText: 'Type the amount',
),
controller: _controller,
),
const SizedBox(height: 20),
OutlinedButton(
child:const Text('OK'),
onPressed: () => _doTheMath(),
),
const SizedBox(height: 20),
if(fees != null)
Text('fee: $fees'),
const SizedBox(height: 20),
if(takeHome != null)
Text('takeHome: $takeHome'),
]),
),
);
}
_doTheMath(){
//perform validation then do the math
double? amount = double.tryParse(_controller.text);
if(amount != null) {
setState((){
final serviceFee = amount * 0.02;
fees = serviceFee;
takeHome = amount - serviceFee;
});
} else {
print('Invalid input');
setState((){
fees = null;
takeHome = null;
});
}
}
}
use double.parse(value) to be able to assign value to the double declared values

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()
]),
),
);
}
}