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

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

Related

Alert Dialog not working as expected in flutter

I was trying to show 2 dialog same time and when i open second dialog, its not focusing on the widget that was in second dialog, its focusing on the widget thats on first dialog that i have opened before.
Is this issue or am i not supposed to open 2 dialog at same time?
Here is video to the issue
Here is first dialog code
showDialog(
context: context,
builder: (_) =>
AlertDialog(
title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Container(
width: 16,
height: 32,
decoration: BoxDecoration(
color: AppColors.colorFFBC99,
borderRadius: BorderRadius.circular(4),
),
),
const SizedBox(
width: 16,
),
Text(
S.addaRecipe,
style: Theme.of(context).textTheme.headlineSmall!.copyWith(
fontWeight: FontWeight.w600,
color: Colors.black,
),
),
],
),
SizedBox(
width: 300,
child: Row(
children: [
Text(
S.recipeBy,
style: Theme.of(context)
.textTheme
.labelLarge!
.copyWith(fontWeight: FontWeight.w500),
),
SizedBox(
width: 8,
),
Expanded(
child: CustomMyDropDownButton(label: 'dsfsdsf'),
),
],
),
)
],
),
content: Form(
// key: formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Expanded(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(
height: 16,
),
Text(
S.addPhotos,
style: Theme.of(context)
.textTheme
.labelLarge!
.copyWith(fontWeight: FontWeight.w500),
),
const SizedBox(
height: 8,
),
Container(
width: double.infinity,
// height: 200,
color: Colors.white,
child: Wrap(
children: [
for (int i = 0; i < 10; i++)
Padding(
padding: const EdgeInsets.all(8.0),
child: SizedBox(
width: 200,
height: 200,
child: ClipRRect(
borderRadius: BorderRadius.circular(8),
child: Image.network(
S.recipeNetworkImage,
fit: BoxFit.cover,
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: InkWell(
onTap: () {},
child: Container(
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(8),
),
width: 200,
height: 200,
child: const Center(
child: Icon(
Icons.add,
size: 32,
),
),
),
),
),
],
),
),
const SizedBox(
height: 16,
),
CustomTextField(
showLabel: true,
// controller: textEditingController,
label: S.recipeName,
validator: (v) {
if (v!.isEmpty) {
return 'This field is required';
}
return null;
},
),
const SizedBox(
height: 16,
),
CustomTextField(
showLabel: true,
// controller: textEditingController,
label: S.description,
validator: (v) {
if (v!.isEmpty) {
return 'This field is required';
}
return null;
},
),
const SizedBox(
height: 32,
),
Row(
children: [
Text(
S.nutritionalInfo,
style: Theme.of(context)
.textTheme
.labelLarge!
.copyWith(fontWeight: FontWeight.w500),
),
IconButton(
onPressed: () {
showDialog(
context: context,
builder: (_) => AlertDialog(
title: const Text(
S.addNutrition,
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: const [
CustomTextField(
showLabel: true,
label: S.name,
),
CustomTextField(
showLabel: true,
label: S.value,
),
],
),
actions: [
CustomOutlinedButton(
name: S.close,
onPress: () {
context.pop();
}),
CustomElevatedButton(
name: S.add,
onPress: () {},
),
],
),
);
},
icon: const Icon(Icons.add),
)
],
),
const SizedBox(
height: 8,
),
Container(
padding: EdgeInsets.all(8),
color: Colors.grey.shade100,
child: 1 == 1
? Text(
"Nutrition Info....",
)
: Column(
children: [
for (int i = 0; i < 0; i++)
ListTile(
leading:
Icon(Icons.horizontal_split_rounded),
title: Text('Calories'),
subtitle: Text('237'),
trailing: IconButton(
onPressed: () {},
icon: Icon(Icons.delete),
),
),
],
),
),
const SizedBox(
height: 32,
),
Text(
S.steps,
style: Theme.of(context)
.textTheme
.labelLarge!
.copyWith(fontWeight: FontWeight.w500),
),
const SizedBox(
height: 8,
),
Container(
color: AppColors.colorF4F4F4,
height: 300,
width: MediaQuery.of(context).size.width * .8,
child: HtmlEditor(
controller: HtmlEditorController(),
htmlEditorOptions: const HtmlEditorOptions(
hint: "Steps....",
),
otherOptions: const OtherOptions(
height: 400,
decoration: BoxDecoration(color: Colors.red)),
),
),
const SizedBox(
height: 32,
),
],
),
),
),
const SizedBox(
height: 32,
),
Stack(
children: [
Text(
'',
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Colors.red,
),
),
Text(
'',
maxLines: 3,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
color: Colors.green,
),
),
],
),
],
),
),
actions: [
CustomOutlinedButton(
name: S.close,
onPress: () {
context.pop();
}),
CustomElevatedButton(
name: S.add,
onPress: () {},
),
],
);
Here is the code of second dialog show dialog
showDialog(
context: context,
builder: (_) => AlertDialog(
title: const Text(
S.addNutrition,
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: const [
CustomTextField(
showLabel: true,
label: S.name,
),
CustomTextField(
showLabel: true,
label: S.value,
),
],
),
actions: [
CustomOutlinedButton(
name: S.close,
onPress: () {
context.pop();
}),
CustomElevatedButton(
name: S.add,
onPress: () {},
),
],
),
);
Here is customtextfield code
import 'package:flutter/material.dart';
class CustomTextField extends StatefulWidget {
final String? label;
final TextEditingController? controller;
final String? Function(String?)? validator;
final Function(String?)? onSaved;
final bool showLabel;
final bool enableSuggestions;
final bool autocorrect;
final TextInputType? keyBoardType;
final Function(String)? onChange;
final bool showSuffixIcon;
const CustomTextField({
Key? key,
this.label,
this.controller,
this.validator,
this.onSaved,
this.enableSuggestions = true,
this.autocorrect = true,
this.keyBoardType,
this.onChange,
this.showSuffixIcon = false,
this.showLabel = false,
}) : super(key: key);
#override
State<CustomTextField> createState() => _CustomTextFieldState();
}
class _CustomTextFieldState extends State<CustomTextField> {
final textFieldFocusNode = FocusNode();
bool _obscured = false;
#override
void initState() {
// TODO: implement initState
if (widget.showSuffixIcon) {
_obscured = true;
}
super.initState();
}
void _toggleObscured() {
setState(() {
_obscured = !_obscured;
if (textFieldFocusNode.hasPrimaryFocus)
return; // If focus is on text field, dont unfocus
textFieldFocusNode.canRequestFocus =
false; // Prevents focus if tap on eye
});
}
#override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
widget.showLabel
? Text(
widget.label!,
style: Theme.of(context)
.textTheme
.labelLarge!
.copyWith(fontWeight: FontWeight.w500),
)
: const SizedBox(),
SizedBox(
height: widget.showLabel ? 8 : 0,
),
TextFormField(
controller: widget.controller,
validator: widget.validator,
onSaved: widget.onSaved,
onChanged: widget.onChange,
focusNode: textFieldFocusNode,
obscureText: _obscured,
enableSuggestions: widget.enableSuggestions,
autocorrect: widget.autocorrect,
keyboardType: widget.keyBoardType,
decoration: InputDecoration(
isDense: true,
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(8),
),
borderSide: BorderSide(
color: Colors.black12,
),
),
focusedBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(8),
),
borderSide: BorderSide(
color: Colors.black12,
),
),
errorBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(8),
),
borderSide: BorderSide(
color: Colors.red,
),
),
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(8),
),
borderSide: BorderSide(
color: Colors.black12,
),
),
labelText: widget.showLabel ? null : widget.label,
// labelStyle: CustomTextStyle.kTextStyle16400.copyWith(
// color: AppColors.textColor2,
// ),
suffixIcon: widget.showSuffixIcon
? Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 4, 0),
child: GestureDetector(
onTap: _toggleObscured,
child: Icon(
_obscured
? Icons.visibility_rounded
: Icons.visibility_off_rounded,
size: 24,
color: Colors.grey,
),
),
)
: null,
),
),
],
);
}
}
Try to add autofocus: true, on your CustomTextField. It should do handle rest I believe.
TextField(
autofocus: true,
);

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

Navigator.pop(context) showing blank

I was trying to navigate back to the first Screen using Navigator.pop(context), but instead it shows a blank screen instead of going back to the first screen.
How do i fix this
MAIN SCREEN
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'GenderButton.dart';
import 'constants.dart';
import 'buttons.dart';
import 'resultpage.dart';
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Center(child: Text('')),
elevation: 0,
actions: [
IconButton(
onPressed: () {},
icon: Icon(
Icons.add_alert_sharp,
size: 35,
))
],
leading: IconButton(
onPressed: () {},
icon: Icon(
Icons.add,
size: 35,
),
),
),
body: HomeScreen());
}
}
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Gender SelectedGender = Gender.empty;
#override
Widget build(BuildContext context) {
return Column(
children: [
//BMI Calculator Header
Row(
children: [
SizedBox(
width: 30,
),
Text(
'BMI Calculator',
style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
],
),
SizedBox(
height: 20,
),
//Gender Text
Row(
children: [
SizedBox(
width: 25,
),
Text(
'Gender',
style: TextStyle(fontSize: 17),
),
],
),
SizedBox(
height: 10,
),
//Button Widget
Row(
children: [
SizedBox(
width: 25,
),
BoxButton(
Type: 'MALE',
BorderColor: SelectedGender == Gender.male
? activeCardColor
: inactiveCardColor,
IconColor:
SelectedGender == Gender.male ? activeCardColor : inactiv,
OnPress: () {
setState(() {
SelectedGender = Gender.male;
});
},
),
SizedBox(
width: 15,
),
BoxButton(
Type: 'FEMALE',
BorderColor: SelectedGender == Gender.female
? activeCardColor
: inactiveCardColor,
IconColor:
SelectedGender == Gender.female ? activeCardColor : inactiv,
OnPress: () {
setState(() {
SelectedGender = Gender.female;
});
},
),
],
),
SizedBox(
height: 20,
),
//Weight Text
Row(
children: [
SizedBox(
width: 25,
),
//Weight Text
Text(
'Weight',
style: TextStyle(fontSize: 15),
)
],
),
SizedBox(
height: 5,
),
Row(
children: [
SizedBox(
width: 25,
),
Container(
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(8)),
// margin: EdgeInsets.all(15),
height: 50,
width: 250,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
RoundedIconButton(
icon: FontAwesomeIcons.minus,
onPressed: () {
setState(() {
Weight--;
});
},
),
SizedBox(
width: 55,
),
Text(
Weight.toString(),
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold),
),
SizedBox(
width: 50,
),
RoundedIconButton(
icon: FontAwesomeIcons.plus,
onPressed: () {
setState(() {
Weight++;
});
},
)
],
),
),
SizedBox(
width: 10,
),
Container(
height: 50,
width: 100,
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(9)),
)
],
),
SizedBox(
height: 20,
),
//Height Text
Row(
children: [
SizedBox(
width: 25,
),
Text(
'Height',
style: TextStyle(fontSize: 15),
)
],
),
Row(
children: [
SizedBox(
width: 25,
),
Container(
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(8)),
// margin: EdgeInsets.all(15),
height: 50,
width: 250,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
RoundedIconButton(
icon: FontAwesomeIcons.minus,
onPressed: () {
setState(() {
Height--;
});
},
),
SizedBox(
width: 55,
),
Text(
Height.toString(),
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold),
),
SizedBox(
width: 50,
),
RoundedIconButton(
icon: FontAwesomeIcons.plus,
onPressed: () {
setState(() {
Height++;
});
},
)
],
),
),
SizedBox(
width: 10,
),
Container(
height: 50,
width: 100,
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(9)),
)
],
),
SizedBox(
height: 20,
),
Row(
children: [
SizedBox(
width: 25,
),
Text(
'Age',
style: TextStyle(fontSize: 18),
)
],
),
SizedBox(
height: 5,
),
Container(
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(8)),
height: 50,
width: 369,
child: Container(
// margin: EdgeInsets.all(15),
height: 50,
width: 250,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
RoundedIconButton(
icon: FontAwesomeIcons.minus,
onPressed: () {
setState(() {
Age--;
});
},
),
SizedBox(
width: 100,
),
Text(
Age.toString(),
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold),
),
SizedBox(
width: 110,
),
RoundedIconButton(
icon: FontAwesomeIcons.plus,
onPressed: () {
setState(() {
Age++;
});
},
)
],
),
),
),
SizedBox(
height: 20,
),
GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ResultPage();
}));
},
child: Container(
decoration: BoxDecoration(
color: Color(0xFF06C46C),
borderRadius: BorderRadius.circular(8)),
height: 50,
width: 369,
child: Center(
child: Text(
'Calculate',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
)),
),
),
],
);
}
}
SCREEN 2
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class ResultPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(
scaffoldBackgroundColor: Colors.black,
textTheme: TextTheme(
bodyText2: TextStyle(color: Colors.white),
),
colorScheme: ColorScheme.light(
primary: Colors.black, secondary: Colors.black)),
home: Scaffold(
appBar: AppBar(
title: Center(child: Text('')),
elevation: 0,
actions: [
IconButton(
onPressed: () {},
icon: Icon(
Icons.add_alert_sharp,
size: 35,
))
],
leading: IconButton(
onPressed: () {},
icon: Icon(
Icons.add,
size: 35,
),
),
),
body: Results()),
);
}
}
class Results extends StatefulWidget {
#override
_ResultsState createState() => _ResultsState();
}
class _ResultsState extends State<Results> {
#override
Widget build(BuildContext context) {
return Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Result',
style: TextStyle(fontSize: 30),
),
Center(
child: Container(
decoration: BoxDecoration(
color: Color(0xFF333335),
borderRadius: BorderRadius.circular(8)),
margin: EdgeInsets.all(10),
height: 300,
width: 350,
),
),
Center(
child: Container(
margin: EdgeInsets.all(35),
child: Text('For your height , a normal would be from 48.6 '
'to 63.3 kilograms'),
),
),
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Container(
decoration: BoxDecoration(
color: Color(0xFF06C46C),
borderRadius: BorderRadius.circular(8)),
height: 50,
width: 369,
child: Center(
child: Text(
'Recalculate BMI',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
)),
),
),
],
),
);
}
}
and also if you look at how i position all my widget to get same styling of a design i saw on dribble enter link description here am doing it right ? because i feel like i am doing it the wrong way and am still a beginner and i was trying to recreate what i learnt from a course i bought on udemy?
Try below code hope its help to you. set rootNavigator: true
Refer Naviagtion here , here, here
Navigator.of(
context,
rootNavigator: true,
).pop(
context,
);
Or try below solution also
Navigator.pop(context);
Full Code:
import 'package:flutter/material.dart';
void main() {
runApp(const MaterialApp(
title: 'Navigation Basics',
home: FirstRoute(),
));
}
class FirstRoute extends StatelessWidget {
const FirstRoute({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('First Route'),
),
body: Center(
child: ElevatedButton(
child: const Text('Open route'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SecondRoute()),
);
},
),
),
);
}
}
class SecondRoute extends StatefulWidget {
const SecondRoute({Key? key}) : super(key: key);
#override
State<SecondRoute> createState() => _SecondRouteState();
}
class _SecondRouteState extends State<SecondRoute> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Second Route"),
),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Go back!'),
),
),
);
}
}
Test this code here

The method 'RippleIndicator' isn't defined for the type '_MyCardWidgetState'

I am trying to add google maps to my app. but I'm getting method isn't defined error.
ERRORS:
The method 'RippleIndicator' isn't defined for the type '_MyCardWidgetState'.
Try correcting the name to the name of an existing method, or defining a method named
'RippleIndicator'.
The method 'mapWidget' isn't defined for the type '_MyCardWidgetState'.
Try correcting the name to the name of an existing method, or defining a method named
'mapWidget'.
The value of the field '_child' isn't used.
Try removing the field, or using it.
Full code of my dart file
import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'add_new.dart';
class CompanyDataBody extends StatelessWidget {
CompanyDataBody({
Key key,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
backgroundColor: Colors.white,
centerTitle: true,
leading: Padding(
padding: EdgeInsets.only(left: 12),
child: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.black),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => AddNewBody()),
),
),
),
title: Text(
"COMPANY DATA",
style: TextStyle(
color: Color(4293492024),
),
),
actions: <Widget>[
IconButton(
icon: Image.asset('assets/icons/download_logo.png'),
tooltip: 'Download logo',
onPressed: () {},
),
],
),
//backgroundColor: Colors.yellow,
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/main_bottom.png"),
alignment: Alignment.bottomCenter,
fit: BoxFit.cover,
),
),
child: MyCardWidget(),
),
),
);
}
}
/// This is the stateless widget that the main application instantiates.
class MyCardWidget extends StatefulWidget {
MyCardWidget({Key key}) : super(key: key);
#override
_MyCardWidgetState createState() => _MyCardWidgetState();
}
class _MyCardWidgetState extends State<MyCardWidget> {
Set<Marker> _createMarker() {
return <Marker>[
Marker(
markerId: MarkerId("current_location"),
position: LatLng(position.latitude, position.longitude),
icon: BitmapDescriptor.defaultMarker,
infoWindow: InfoWindow(title: "Current Location"),
),
].toSet();
}
// ignore: unused_field
GoogleMapController _controller;
Position position;
Widget _child;
#override
void initState() {
//Todo: implement initState
_child = RippleIndicator("Getting Location");
getCurrentLocation();
super.initState();
}
void getCurrentLocation() async {
Position res = await Geolocator().getCurrentPosition();
setState(() {
position = res;
_child = mapWidget();
});
}
#override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
Container(
alignment: Alignment.topCenter,
child: Padding(
padding: const EdgeInsets.only(top: 10, left: 50.0),
child: Column(
children: [
SizedBox(
child: Row(
children: [
Text(
'Company Data',
style: TextStyle(
fontFamily: 'Arial',
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.black,
height: 2,
),
textAlign: TextAlign.center,
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: Container(
margin: EdgeInsets.only(top: 10),
height: 3.0,
width: 200.0,
color: Color(4293492024),
),
),
],
),
),
],
),
),
),
Column(
children: [
MaterialButton(
onPressed: () {},
color: Color(4293492024),
textColor: Colors.white,
child: Icon(
Icons.camera_alt,
size: 24,
),
padding: EdgeInsets.all(16),
shape: CircleBorder(),
),
Text(
"Add Logo",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Colors.black,
),
),
],
),
SizedBox(
height: 20,
),
Column(
children: [
Text(
"Project Name",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Container(
width: 300,
margin: EdgeInsets.all(5),
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Color(4293492024), width: 3.0),
borderRadius: BorderRadius.all(Radius.circular(50.0)),
),
child: TextField(
decoration: InputDecoration(
hintText: 'Project Name',
border: InputBorder.none,
),
),
),
Text(
"Project Number",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Container(
width: 300,
margin: EdgeInsets.all(5),
padding: EdgeInsets.all(5),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Color(4293492024), width: 3.0),
borderRadius: BorderRadius.all(Radius.circular(50.0)),
),
child: TextField(
decoration: InputDecoration(
hintText: 'Number of workers',
border: InputBorder.none,
),
),
),
],
),
Container(
height: 200,
width: 400,
child: GoogleMap(
mapType: MapType.normal,
markers: _createMarker(),
initialCameraPosition: CameraPosition(
target: LatLng(position.latitude, position.longitude),
zoom: 12.0,
),
onMapCreated: (GoogleMapController controller) {
_controller = controller;
},
),
),
ElevatedButton(
child: Text("Next"),
onPressed: () => Navigator.push(
context,
MaterialPageRoute(builder: (context) => AddNewBody()),
),
style: ElevatedButton.styleFrom(
primary: Color(4293492024),
onPrimary: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(32.0),
),
),
)
],
),
);
}
}
I have added all dependencies.
pubspec.yaml file
dependencies:
google_maps_flutter: 0.5.30
geolocator: 5.1.2
location: 3.0.2
url_launcher: 5.7.5
flappy_search_bar: 1.4.1

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