Related
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'),
),
);
});
}
}
I am trying to make an edit page for users to update their details. I am able to edit the details. But when I leave the page the values go back to the original value it was before editing. How do I make the value stay?
Here is how the screen looks like -
Screen Picture
I did wrap the values in set state thinking that they would remain after leaving the page but they dont.
import 'package:flutter/material.dart';
import 'package:flutter/painting.dart';
import 'package:my_plate/screens/home_screen.dart';
import 'package:my_plate/screens/user_guide_screen.dart';
import 'package:my_plate/widgets/app_drawer.dart';
class EditProfilePage extends StatefulWidget {
static String routeName = '/profile';
#override
_EditProfilePageState createState() => _EditProfilePageState();
}
class _EditProfilePageState extends State<EditProfilePage> {
final myController = TextEditingController();
final myController1 = TextEditingController();
String name = 'carolyn1234';
String email = 'carolyn#gmail.com';
final formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
title: Text('Profile'),
backgroundColor: Color(0xff588157),
elevation: 1,
// leading: IconButton(
// icon: Icon(
// Icons.arrow_back,
// color: Colors.white,
// ),
// onPressed: () {
// Navigator.of(context).pushNamed(MainScreen.routeName);
// },
// ),
actions: [
IconButton(
icon: Icon(Icons.library_books_outlined),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => UserGuideListScreen(),
));
},
),
],
),
body: Container(
padding: EdgeInsets.only(left: 16, top: 25, right: 16),
child: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: Form(
key: formKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: ListView(
children: [
Text(
"Profile",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 25, fontWeight: FontWeight.w800),
),
SizedBox(
height: 15,
),
Center(
child: Stack(
children: [
Container(
width: 130,
height: 130,
decoration: BoxDecoration(
border: Border.all(
width: 4,
color: Theme.of(context)
.scaffoldBackgroundColor),
boxShadow: [
BoxShadow(
spreadRadius: 2,
blurRadius: 10,
color: Colors.black.withOpacity(0.1),
offset: Offset(0, 10))
],
shape: BoxShape.circle,
image: DecorationImage(
fit: BoxFit.cover,
image: NetworkImage(
"https://i.postimg.cc/gj4CDtjX/image.png",
))),
),
Positioned(
bottom: 0,
right: 0,
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
width: 4,
color:
Theme.of(context).scaffoldBackgroundColor,
),
color: Color(0xff588157),
),
child: Icon(
Icons.edit,
color: Colors.white,
),
)),
],
),
),
SizedBox(
height: 35,
),
Text(
'User Details',
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20),
),
SizedBox(height: 10),
Text('Username',
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w400,
color: Colors.black54)),
SizedBox(height: 5),
Container(
child: Text(name),
// margin: const EdgeInsets.all(2.0),
padding: const EdgeInsets.all(10.0),
width: 2000,
decoration: BoxDecoration(
border: Border.all(color: Colors.blueGrey)),
alignment: Alignment.topLeft,
),
SizedBox(height: 10),
Text('Email',
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w400,
color: Colors.black54)),
SizedBox(height: 5),
Container(
child: Text(email),
// margin: const EdgeInsets.all(2.0),
padding: const EdgeInsets.all(10.0),
width: 2000,
decoration: BoxDecoration(
border: Border.all(color: Colors.blueGrey)),
alignment: Alignment.topLeft,
),
SizedBox(
height: 35,
),
Text(
'Edit Details',
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20),
),
SizedBox(
height: 15,
),
TextFormField(
controller: myController,
// initialValue: 'bla123',
// enabled: false,
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xff588157),
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xff588157),
width: 0.0,
),
),
label: Text('Username',
style: TextStyle(color: Colors.black)),
),
validator: (username) {
if (username == null || username.isEmpty)
return 'Field is required.';
else if (username.length < 8)
return 'Please enter a description that is at least 8 characters.';
else
return null;
},
),
SizedBox(
height: 15,
),
TextFormField(
controller: myController1,
// initialValue: 'bla#gmail.com',
// enabled: false,
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xff588157),
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xff588157),
width: 0.0,
),
),
label:
Text('Email', style: TextStyle(color: Colors.black)),
),
validator: (email) {
if (email == null || email.isEmpty)
return 'Field is required.';
String pattern = r'\w+#\w+\.\w+';
if (!RegExp(pattern).hasMatch(email))
return 'Invalid E-mail Address format.';
return null;
},
),
// DropdownButtonFormField(
// // onChanged: null,
// hint: Text('Female'),
// decoration: InputDecoration(
// label: Text('Gender'),
// ),
// items: [
// DropdownMenuItem(child: Text('Female'), value: 'female'),
// DropdownMenuItem(child: Text('Male'), value: 'male'),
// ],
// onChanged: (String? value) {},
// ),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: () {
final isValidForm = formKey.currentState!.validate();
if (isValidForm) {
setState(() {
name = myController.text;
email = myController1.text;
});
}
setState(() {
// name = myController.text;
// email = myController1.text;
});
},
color: Color(0xff588157),
padding: EdgeInsets.symmetric(horizontal: 30),
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
child: Text(
"Update Details",
style: TextStyle(
fontSize: 15,
letterSpacing: 2.2,
color: Colors.white),
),
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: () {
showAlertDialog();
// setState(() {
//
//
// // name = myController.text;
// // email = myController1.text;
// });
},
color: Color(0xff588157),
padding: EdgeInsets.symmetric(horizontal: 30),
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20)),
child: Text(
"Delete Account",
style: TextStyle(
fontSize: 15,
letterSpacing: 2.2,
color: Colors.white),
),
)
],
)
],
),
),
),
),
drawer: AppDrawer());
}
void showAlertDialog() {
// set up the buttons
Widget cancelButton = TextButton(
child: Text("No", style: TextStyle(color: Color(0xff588157))),
onPressed: () {
Navigator.pop(context);
},
);
Widget continueButton = TextButton(
child: Text("Yes", style: TextStyle(color: Color(0xff588157))),
onPressed: () {
setState(() {
name = '';
email = '';
});
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Account deleted successfully!'),
));
Navigator.pop(context);
},
);
// set up the AlertDialog
AlertDialog alert = AlertDialog(
title: Text("AlertDialog"),
content: Text("Are you sure you want to submit this form?"),
actions: [
cancelButton,
continueButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
}
class Chest extends StatefulWidget {
const Chest({Key? key}) : super(key: key);
#override
_ChestState createState() => _ChestState();
}
class _ChestState extends State<Chest> {
//! Firebase SetUp
final _formKey = GlobalKey<FormState>();
FirebaseAuth auth = FirebaseAuth.instance;
final _firestore = FirebaseFirestore.instance;
late String _email;
late String _password;
#override
Widget build(BuildContext context) {
return Column(children: [
Padding(
padding: const EdgeInsets.only(top: 100.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'BMI CALCULATOR',
style: TextStyle(
fontSize: 35,
color: Colors.white,
fontWeight: FontWeight.normal),
),
Text(
"WELCOME Mr.Dheer",
style: TextStyle(fontSize: 18, color: Colors.white),
)
],
),
),
SizedBox(height: 100),
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(60),
topRight: Radius.circular(60),
),
),
child: Padding(
padding: const EdgeInsets.only(top: 80.0, right: 50, left: 50),
child: Column(
children: [
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(10),
),
boxShadow: [
BoxShadow(
color: Color.fromRGBO(225, 95, 27, .3),
blurRadius: 20,
offset: Offset(0, 10),
),
],
),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
onChanged: (value) {
setState(() {
_email = value;
});
},
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: "Email or Phone Number"),
),
TextFormField(
keyboardType: TextInputType.text,
enabled: true,
onChanged: (value) {
setState(() {
_password = value;
});
},
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: "PassWord"),
),
],
),
),
),
SizedBox(
height: 40,
),
Text(
'FORGOT PASSWORD',
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(
height: 30,
),
Row(
// mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ReuseButton(
OwnTextButton: TextButton(
//! LOGIN FUNCTIONALITY
onPressed: () {},
// Navigator.pushNamed(context, '/HomePage'),
child: Text(
'LOGIN',
style: TextStyle(
color: Colors.white,
),
),
),
OwnBoxColor: Colors.orange.shade700,
),
SizedBox(
width: 10,
),
ReuseButton(
OwnTextButton: TextButton(
// ! REGISTER FUNCTIONALITY
onPressed: () {
Navigator.pushNamed(context, '/SignUpPage');
},
child: Text(
'Register',
style: TextStyle(
color: Colors.white,
),
),
),
OwnBoxColor: Colors.orange.shade700,
)
],
),
SizedBox(
height: 110,
),
Text(
'Continue With Social Media',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 20),
Row(
children: [
ReuseButton(
OwnBoxColor: Colors.blue,
OwnTextButton: TextButton(
onPressed: () {},
child: Text(
'Facebook',
style: TextStyle(
color: Colors.white,
),
),
),
),
SizedBox(
width: 10,
),
ReuseButton(
OwnBoxColor: Colors.black,
OwnTextButton: TextButton(
onPressed: () {},
child: Text(
'Gmail',
style: TextStyle(
color: Colors.white,
),
),
),
)
],
)
],
),
),
),
),
]);
}
}
class ReuseButton extends StatelessWidget {
const ReuseButton({required this.OwnBoxColor, required this.OwnTextButton});
final Color OwnBoxColor;
final TextButton OwnTextButton;
#override
Widget build(BuildContext context) {
return Expanded(
child: Container(
decoration: BoxDecoration(
color: OwnBoxColor,
borderRadius: BorderRadius.all(
Radius.circular(10),
),
),
child: OwnTextButton,
),
);
}
}
Try below code hope its helpful to you. wrap your inside Expanded Widget Column with SingleChildScrollView(). Just chnage your widget with my Widget/Code.
Column(
children: [
Padding(
padding: const EdgeInsets.only(top: 100.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'BMI CALCULATOR',
style: TextStyle(
fontSize: 35,
color: Colors.black,
fontWeight: FontWeight.normal,
),
),
Text(
"WELCOME Mr.Dheer",
style: TextStyle(
fontSize: 18,
color: Colors.black,
),
)
],
),
),
SizedBox(height: 100),
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(60),
topRight: Radius.circular(60),
),
),
child: Padding(
padding:
const EdgeInsets.only(top: 80.0, right: 50, left: 50),
child: SingleChildScrollView(
child: Column(
children: [
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(10),
),
boxShadow: [
BoxShadow(
color: Color.fromRGBO(225, 95, 27, .3),
blurRadius: 20,
offset: Offset(0, 10),
),
],
),
child: Form(
child: Column(
children: [
TextFormField(
onChanged: (value) {
setState(() {});
},
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: "Email or Phone Number",
),
),
TextFormField(
keyboardType: TextInputType.text,
enabled: true,
onChanged: (value) {
setState(() {});
},
decoration: const InputDecoration(
border: UnderlineInputBorder(),
labelText: "PassWord",
),
),
],
),
),
),
SizedBox(
height: 40,
),
Text(
'FORGOT PASSWORD',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 30,
),
Row(
children: [
Text(
'LOGIN',
style: TextStyle(
color: Colors.red,
),
),
SizedBox(
width: 10,
),
Text(
'Register',
style: TextStyle(
color: Colors.red,
),
),
],
),
SizedBox(
height: 110,
),
Text(
'Continue With Social Media',
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 20),
Row(
children: [
Text(
'Facebook',
style: TextStyle(
color: Colors.red,
),
),
SizedBox(
width: 10,
),
Text(
'Gmail',
style: TextStyle(
color: Colors.red,
),
),
],
)
],
),
),
),
),
),
],
),
Your result Scrren->
You can wrap your code in ListView or SingleChildScrollView instead of the column :
#override
Widget build(BuildContext context) {
return ListView(
children: [
// your code
],
);
}
Wrap your code in SingleChildScrollView like below:
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: [
// your rest code here...
],
),
);
}
I'm a beginner in the flutter, I have a conflict, when I'm focusing on a TexFiled, the keyboard hidden over the TextField, and bottom button not showing i attached my conflict here
any solution for this
Thanks
code here
import 'dart:ui';
import 'package:crapp/pages/create_password/password_screen.dart';
import 'package:crapp/widgets/components/alert.dart';
import 'package:crapp/widgets/components/page_animation.dart';
import 'package:crapp/widgets/theme/constants.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:crapp/provider/theme_provider.dart';
class PasswordScreen extends StatefulWidget {
#override
_PasswordScreenState createState() => _PasswordScreenState();
}
class _PasswordScreenState extends State< PasswordScreen > {
final _controller = TextEditingController();
//validation controller
TextEditingController sQuastionController = new TextEditingController();
TextEditingController answerQController = new TextEditingController();
TextEditingController passController = new TextEditingController();
TextEditingController conPassController = new TextEditingController();
final TextEditingController _pass = TextEditingController();
final TextEditingController _confirmPass = TextEditingController();
bool _isButtonEnabled = false;
//final _controller = TextEditingController();
bool isConfirm=false;
check (BuildContext context){
if(sQuastionController.text.isNotEmpty &&
answerQController.text.isNotEmpty &&
conPassController.text.isNotEmpty &&
passController.text.isNotEmpty){
setState(() {
_isButtonEnabled = true;
});
} else {
setState(() {
_isButtonEnabled = false;
});
}
}
checks (BuildContext context){
if(passController.text.isEmpty){
showDialog<void>(
context: context,
builder: (BuildContext dialogContext) {
return Alert(title: "Alert !!!",subTile: "Password must be 10 characters !",);
}
);
}else if(passController.text.length > 0 && passController.text.length < 10){
isConfirm = true;
showDialog<void>(
context: context,
builder: (BuildContext dialogContext) {
return Alert(title: "Alert !!!",subTile: "Password doesn't match !",);
}
);
}
}
checkChanged(){
if( secretVal != null
)
{
setState(() {
isSave = true;
});
}else{
isSave =false;
}
} bool isSave=false;
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
/* double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;*/
Provider.of<ThemeProvider>(context).themeMode == ThemeMode.dark
? 'DarkTheme'
: 'LightTheme';
return Scaffold(
resizeToAvoidBottomInset: false,
body: SafeArea(
child: Column(
children: <Widget>[
Expanded(
child: _signUp(),
),
],
),
), bottomNavigationBar: BottomAppBar(
elevation: 4,
child: Container(
height: 70,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Row(
children: [
Expanded(
child: MaterialButton(
height: 44,
onPressed: () {
FocusScope.of(context).requestFocus(FocusNode());
//check();
},
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(4)),
color: Color(0xFF2A3476),
elevation: 0,
highlightElevation: 0,
child: Container(
child: Text(
"Save",
style: TextStyle(
color: Color(0xFF2A3476),
fontSize: 15,
fontFamily: 'medium'),
),
),
),
),
],
),
),
),
),
/* bottomNavigationBar: Container(
padding: EdgeInsets.all(25.0),
decoration: BoxDecoration(color: Colors.white,
),
child: Row(
children: [
Expanded(
child: MaterialButton(
height: 44,
onPressed: () {
FocusScope.of(context).requestFocus(FocusNode());
*//* Navigator.push(context, SlidePageRoute(page:PasswordScreen()));*//*
},
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
color: _isButtonEnabled ? Color(0xFF2A3476) : Color(0x201E1E99),
elevation: 0,
highlightElevation: 0,
child: Container(
child: Text(
"Next",
style: TextStyle(color: m_fillColor,fontSize: 18,fontWeight: FontWeight.w600 ,
fontFamily: "regular",),
),
),
),
),
],
),
)*/
);
}
Widget _signUp() {
return Container(
constraints: BoxConstraints.expand(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
),
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xFF2A3476),
Color(0xFF2A3476),
],
begin: Alignment.topLeft,
end: Alignment.centerRight,
),
),
child: Form(
key: formKey,
child: Container(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding:
const EdgeInsets.symmetric(vertical: 36.0, horizontal: 24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Create Password",
style: TextStyle(
color: Colors.white,
fontSize: 30.0,fontFamily: "medium",
fontWeight: FontWeight.w800,
),
),
],
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30),
),
),
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Steps to set your",
style: TextStyle(
fontSize: 22,
fontFamily: "regular",
fontWeight: FontWeight.w300,
color: Colors.black,
),
),
Text(
"password",
style: TextStyle(
fontSize: 22,
fontFamily: "regular",
fontWeight: FontWeight.w300,
color: Colors.black,
),
),
SizedBox(
height: 20.0,
), Text(
'Secret Question',
style:
TextStyle( fontSize: 15,
fontFamily: "regular",),
), SizedBox(
height: 8.0,
),
Row(
children: [
Expanded(child: InkWell(
onTap: (){
FocusScope.of(context).requestFocus(FocusNode());
secretDialogue();
},
child: Stack(
children: <Widget>[
TextField(
/* textInputAction: TextInputAction.next,*/
controller: sQuastionController,
enabled: false,
onChanged: (val) {
check(context);
},
decoration: InputDecoration(
labelText: secretVal==null?"Select One":secretVal,
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "",
/* prefixIcon: Icon(
Icons.people_outline_rounded,
color: Colors.grey[600],
)*/
),
),
Positioned.directional(
textDirection: Directionality.of(context),
end: 0,
top: 0,
bottom: 0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child:Image.asset(
"assets/icons/ic_drop_arrow.png",
scale: 9,
)),
)
],
),
),
),
],
),
SizedBox(
height: 20.0,
),
Text(
'Answer',
style:
TextStyle( fontSize: 15,
fontFamily: "regular",),
),
SizedBox(
height: 8.0,
),
TextField(
/* keyboardType: TextInputType.emailAddress,*/
/* textInputAction: TextInputAction.next,*/
controller: answerQController,
onChanged: (val){
check(context);
},
decoration: InputDecoration(
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "",
/*prefixIcon: Icon(
Icons.people_outline_rounded,
color: Color(0xFFE1E8F7),
)*/),
),
SizedBox(
height: 20.0,
),
Text(
'Password',
style:
TextStyle( fontSize: 15,
fontFamily: "regular",),
),
SizedBox(
height: 8.0,
),
TextFormField(
/* keyboardType: TextInputType.emailAddress,*/
/* textInputAction: TextInputAction.next,*/
controller: passController,
onChanged: (val){
check(context);
},
//password validation
/* validator: (val){
if(val!.isEmpty)
return 'Empty';
return null;
},*/
decoration: InputDecoration(
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "************",
),
),
SizedBox(
height: 20.0,
),
Text(
'Confirm Password',
style:
TextStyle( fontSize: 15,
fontFamily: "regular",),
),
SizedBox(
height: 8.0,
),
TextFormField(
textInputAction: TextInputAction.done,
controller: conPassController,
onChanged: (val){
check(context);
},
//password validation
/* validator: (val){
if(val!.isEmpty)
return 'Empty';
if(val != _pass.text)
return 'Not Match';
return null;
},*/
decoration: InputDecoration(
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "************",
),
),
SizedBox(
height: 20.0,
),
SizedBox(
height: 8.0,
),
SizedBox(
height:200.0,
),
],
),
),
),
],
),
),
),
),
);
}
//
//Secret Qu Alert
List secretList =[
"-What’s your favorite team?",
"-What’s your astrological sign?",
"-What’s your favorite movie?",
"-What city were you born in?",
"-What was your first car?",
];
var secretVal;
void secretDialogue(){
showDialog<void>(
context: context,
// false = user must tap button, true = tap outside dialog
builder: (BuildContext dialogContext) {
return StatefulBuilder(
builder: (context,setState){
return Dialog(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
insetPadding: EdgeInsets.all(20),
child: Container(
padding: EdgeInsets.symmetric(vertical: 10),
child: Column(
mainAxisSize: MainAxisSize.min,
children: List.generate(secretList.length, (index){
return InkWell(
onTap: (){
setState(() {
secretVal = secretList[index];
Navigator.pop(context);
});
},
child: Container(
height: 50,
padding: EdgeInsets.symmetric(horizontal: 20),
alignment: Alignment.centerLeft,
child: Text(secretList[index],
style: TextStyle(
fontSize: 18,
fontFamily: "medium",
),),
),
);
})
),
),
);
}
);
},
);
}
}
Wrap your Column by SingleChildScrollView. It will solve your problem.
like this..
body: SafeArea(
child: SingleChildScrollView(
child: Column(
Also I think after this there is no need of
resizeToAvoidBottomInset: false,
in Scaffold.
Please check out and I have found some inconsistency in code, refactored some of them
import 'dart:ui';
import 'package:crapp/pages/create_password/password_screen.dart';
import 'package:crapp/widgets/components/alert.dart';
import 'package:crapp/widgets/components/page_animation.dart';
import 'package:crapp/widgets/theme/constants.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:crapp/provider/theme_provider.dart';
class PasswordScreen extends StatefulWidget {
#override
_PasswordScreenState createState() => _PasswordScreenState();
}
class _PasswordScreenState extends State< PasswordScreen > {
final _controller = TextEditingController();
//validation controller
TextEditingController sQuastionController = new TextEditingController();
TextEditingController answerQController = new TextEditingController();
TextEditingController passController = new TextEditingController();
TextEditingController conPassController = new TextEditingController();
final TextEditingController _pass = TextEditingController();
final TextEditingController _confirmPass = TextEditingController();
bool _isButtonEnabled = false;
//final _controller = TextEditingController();
bool isConfirm = false;
check(BuildContext context) {
if (sQuastionController.text.isNotEmpty &&
answerQController.text.isNotEmpty &&
conPassController.text.isNotEmpty &&
passController.text.isNotEmpty) {
setState(() {
_isButtonEnabled = true;
});
} else {
setState(() {
_isButtonEnabled = false;
});
}
}
void initState() {
SystemChannels.textInput.invokeMethod('TextInput.hide');
super.initState();
}
checks (BuildContext context){
if(passController.text.isEmpty){
showDialog<void>(
context: context,
builder: (BuildContext dialogContext) {
return Alert(title: "Alert !!!",subTile: "Password must be 10 characters !",);
}
);
}else if(passController.text.length > 0 && passController.text.length < 10){
isConfirm = true;
showDialog<void>(
context: context,
builder: (BuildContext dialogContext) {
return Alert(title: "Alert !!!",subTile: "Password doesn't match !",);
}
);
}
}
checkChanged() {
if (secretVal != null) {
setState(() {
isSave = true;
});
} else {
isSave = false;
}
}
bool isSave = false;
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
/* double height = MediaQuery.of(context).size.height;
double width = MediaQuery.of(context).size.width;*/
Provider.of<ThemeProvider>(context).themeMode == ThemeMode.dark
? 'DarkTheme'
: 'LightTheme';
return Scaffold(
// resizeToAvoidBottomInset: false,
body: _signUp(),
bottomNavigationBar: BottomAppBar(
elevation: 4,
child: Container(
height: 70,
child: Container(
padding: EdgeInsets.symmetric(horizontal: 16),
child: Row(
children: [
Expanded(
child: MaterialButton(
height: 44,
onPressed: () {
FocusScope.of(context).requestFocus(FocusNode());
//check();
},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4)),
color: Color(0xFF2A3476),
elevation: 0,
highlightElevation: 0,
child: Container(
child: Text(
"Save",
style: TextStyle(
color: Color(0xFF2A3476),
fontSize: 15,
fontFamily: 'medium'),
),
),
),
),
],
),
),
),
),
/* bottomNavigationBar: Container(
padding: EdgeInsets.all(25.0),
decoration: BoxDecoration(color: Colors.white,
),
child: Row(
children: [
Expanded(
child: MaterialButton(
height: 44,
onPressed: () {
FocusScope.of(context).requestFocus(FocusNode());
*/ /* Navigator.push(context, SlidePageRoute(page:PasswordScreen()));*/ /*
},
shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))),
color: _isButtonEnabled ? Color(0xFF2A3476) : Color(0x201E1E99),
elevation: 0,
highlightElevation: 0,
child: Container(
child: Text(
"Next",
style: TextStyle(color: m_fillColor,fontSize: 18,fontWeight: FontWeight.w600 ,
fontFamily: "regular",),
),
),
),
),
],
),
)*/
);
}
Widget _signUp() {
return Container(
width: MediaQuery.of(context).size.width,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color(0xFF2A3476),
Color(0xFF2A3476),
],
begin: Alignment.topLeft,
end: Alignment.centerRight,
),
),
child: SingleChildScrollView(
child: Form(
key: formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(
vertical: 36.0, horizontal: 24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Create Password",
style: TextStyle(
color: Colors.white,
fontSize: 30.0,
fontFamily: "medium",
fontWeight: FontWeight.w800,
),
),
],
),
),
Container(
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30),
),
),
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Steps to set your",
style: TextStyle(
fontSize: 22,
fontFamily: "regular",
fontWeight: FontWeight.w300,
color: Colors.black,
),
),
Text(
"password",
style: TextStyle(
fontSize: 22,
fontFamily: "regular",
fontWeight: FontWeight.w300,
color: Colors.black,
),
),
SizedBox(
height: 20.0,
),
Text(
'Secret Question',
style: TextStyle(
fontSize: 15,
fontFamily: "regular",
),
),
SizedBox(
height: 8.0,
),
Row(
children: [
Expanded(
child: InkWell(
onTap: () {
FocusScope.of(context)
.requestFocus(FocusNode());
secretDialogue();
},
child: Stack(
children: <Widget>[
TextField(
/* textInputAction: TextInputAction.next,*/
controller: sQuastionController,
enabled: false,
onChanged: (val) {
check(context);
},
decoration: InputDecoration(
labelText: secretVal == null
? "Select One"
: secretVal,
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius:
BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "",
/* prefixIcon: Icon(
Icons.people_outline_rounded,
color: Colors.grey[600],
)*/
),
),
Positioned.directional(
textDirection: Directionality.of(context),
end: 0,
top: 0,
bottom: 0,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset(
"assets/icons/ic_drop_arrow.png",
scale: 9,
)),
)
],
),
),
),
],
),
SizedBox(
height: 20.0,
),
Text(
'Answer',
style: TextStyle(
fontSize: 15,
fontFamily: "regular",
),
),
SizedBox(
height: 8.0,
),
GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
},
child: TextField(
/* keyboardType: TextInputType.emailAddress,*/
/* textInputAction: TextInputAction.next,*/
controller: answerQController,
onChanged: (val) {
check(context);
},
decoration: InputDecoration(
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "",
/*prefixIcon: Icon(
Icons.people_outline_rounded,
color: Color(0xFFE1E8F7),
)*/
),
),
),
SizedBox(
height: 20.0,
),
Text(
'Password',
style: TextStyle(
fontSize: 15,
fontFamily: "regular",
),
),
SizedBox(
height: 8.0,
),
GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
},
child: TextFormField(
/* keyboardType: TextInputType.emailAddress,*/
/* textInputAction: TextInputAction.next,*/
controller: passController,
onChanged: (val) {
check(context);
},
//password validation
/* validator: (val){
if(val!.isEmpty)
return 'Empty';
return null;
},*/
decoration: InputDecoration(
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "************",
),
),
),
SizedBox(
height: 20.0,
),
Text(
'Confirm Password',
style: TextStyle(
fontSize: 15,
fontFamily: "regular",
),
),
SizedBox(
height: 8.0,
),
GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
},
child: TextFormField(
textInputAction: TextInputAction.done,
controller: conPassController,
onChanged: (val) {
check(context);
},
//password validation
/* validator: (val){
if(val!.isEmpty)
return 'Empty';
if(val != _pass.text)
return 'Not Match';
return null;
},*/
decoration: InputDecoration(
contentPadding: EdgeInsets.all(8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8.0),
borderSide: BorderSide.none,
),
filled: true,
fillColor: Color(0xFFE1E8F7),
hintText: "************",
),
),
),
SizedBox(
height: 20.0,
),
SizedBox(
height: 8.0,
),
SizedBox(
height: 200.0,
),
],
),
),
),
],
),
),
),
);
}
//
//Secret Qu Alert
List secretList = [
"-What’s your favorite team?",
"-What’s your astrological sign?",
"-What’s your favorite movie?",
"-What city were you born in?",
"-What was your first car?",
];
var secretVal;
void secretDialogue() {
showDialog<void>(
context: context,
// false = user must tap button, true = tap outside dialog
builder: (BuildContext dialogContext) {
return StatefulBuilder(builder: (context, setState) {
return Dialog(
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
insetPadding: EdgeInsets.all(20),
child: Container(
padding: EdgeInsets.symmetric(vertical: 10),
child: Column(
mainAxisSize: MainAxisSize.min,
children: List.generate(secretList.length, (index) {
return InkWell(
onTap: () {
setState(() {
secretVal = secretList[index];
Navigator.pop(context);
});
},
child: Container(
height: 50,
padding: EdgeInsets.symmetric(horizontal: 20),
alignment: Alignment.centerLeft,
child: Text(
secretList[index],
style: TextStyle(
fontSize: 18,
fontFamily: "medium",
),
),
),
);
})),
),
);
});
},
);
}
}
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()
]),
),
);
}
}