This is a flutter code that I created and the error text that is all the way at the bottom won't appear for some reason. I have created a login page that looks similar to this and it works fine but in that one, I am using onChanged instead of onSaved. I tried using it for this one but the keyboard would appear and disappear once I started typing while using onChanged so I used onSaved and that went away.
import 'package:flutter/material.dart';
import 'package:note_taker/authenticate/auth.dart';
import 'package:note_taker/shared/constants.dart';
class SignUp extends StatefulWidget {
final Function toggleView;
SignUp({#required this.toggleView});
#override
_SignUpState createState() => _SignUpState();
}
class _SignUpState extends State<SignUp> {
#override
Widget build(BuildContext context) {
final AuthService _auth = AuthService();
String _email;
String _password;
String error = '';
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
Widget _buildHelloThere() {
return Container(
child: Column(
children: [
Container(
child: Stack(
children: [
Container(
// container for the HELLO TEXT
padding: EdgeInsets.only(
top: 80,
left: 20,
right: 0,
bottom: 0,
),
child: Text(
'HELLO',
style: TextStyle(
color: Colors.black,
fontSize: 60,
fontWeight: FontWeight.w900,
),
),
),
Container(
// container for the TEXT TEXT
padding: EdgeInsets.only(
top: 130,
left: 20,
right: 0,
bottom: 0,
),
child: Text(
'NEW',
style: TextStyle(
color: Colors.black,
fontSize: 60,
fontWeight: FontWeight.w900,
),
),
),
Container(
// container for the . TEXT
padding: EdgeInsets.only(
top: 130,
left: 160,
right: 0,
bottom: 0,
),
child: Text(
'USER',
style: TextStyle(
color: Colors.teal,
fontSize: 60,
fontWeight: FontWeight.w900,
),
),
),
],
),
),
],
),
);
}
Widget _buildEmail() {
return Container(
padding: EdgeInsets.symmetric(horizontal: 20),
child: TextFormField(
decoration: textDecorationForInput.copyWith(
labelText: 'Email',
labelStyle: TextStyle(color: Colors.teal),
),
validator: (value) {
Pattern pattern =
r'^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
RegExp regex = new RegExp(pattern);
if (value.isEmpty) {
return 'Email Required';
} else if (!regex.hasMatch(value)) {
return 'Enter Valid Email';
}
return null;
},
onSaved: (newValue) {
setState(() {
_email = newValue;
});
},
),
);
}
Widget _buildPassword() {
return Container(
padding: EdgeInsets.only(top: 30, left: 20, right: 20),
child: TextFormField(
decoration: textDecorationForInput.copyWith(
labelText: 'Password',
labelStyle: TextStyle(color: Colors.teal),
),
validator: (value) {
if (value.isEmpty) {
return 'Password Required';
} else if (value.length < 6) {
return 'Password too Small';
}
return null;
},
onSaved: (newValue) {
setState(() {
_password = newValue;
});
},
obscureText: true,
),
);
}
Widget _createSubmitButton() {
return Center(
child: RaisedButton(
color: Colors.teal,
padding: EdgeInsets.symmetric(horizontal: 130, vertical: 10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
child: Text(
'Sign In',
style: TextStyle(
color: Colors.white,
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
dynamic result =
await _auth.signUpWithEmailAndPassword(_email, _password);
if (result == null) {
setState(() {
error = 'Problem with creating account';
});
}
}
},
),
);
}
Widget _createSignInButton() {
// to toggle between between sign up and log in
return FlatButton(
padding: EdgeInsets.only(left: 320),
onPressed: () {
//toggleView;
widget.toggleView();
},
child: Text(
'Sign up',
style: TextStyle(
color: Colors.blue,
fontSize: 20,
),
),
);
}
// this screen is next
return Scaffold(
resizeToAvoidBottomInset: true,
body: SingleChildScrollView(
child: Form(
key: _formKey,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// build a text that says the word Hello
// build a text that says New
// build a tex that say User
_buildHelloThere(),
// create the text field for email
SizedBox(
height: 40,
),
_buildEmail(),
// create the text field for password
_buildPassword(),
//log in button
_createSignInButton(),
SizedBox(
height: 90,
),
// submit button
_createSubmitButton(),
// error print out
Center(
child: Text(
error,
style: TextStyle(
color: Colors.red,
fontSize: 20,
),
),
),
],
),
),
),
),
);
}
}
You can copy paste run full code below
Step 1: You declare variables inside build, you have to move them outside of build , to avoid when Sing-In fail and setState will reset these variable
code snippet
final AuthService _auth = AuthService();
String _email;
String _password;
String error = '';
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
Step 2: You do not need setState in onSaved
working demo
full code
import 'package:flutter/material.dart';
class AuthService {
signUpWithEmailAndPassword(String email, String password) {
return null;
}
}
class SignUp extends StatefulWidget {
final Function toggleView;
SignUp({#required this.toggleView});
#override
_SignUpState createState() => _SignUpState();
}
class _SignUpState extends State<SignUp> {
final AuthService _auth = AuthService();
String _email;
String _password;
String error = '';
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
Widget _buildHelloThere() {
return Container(
child: Column(
children: [
Container(
child: Stack(
children: [
Container(
// container for the HELLO TEXT
padding: EdgeInsets.only(
top: 80,
left: 20,
right: 0,
bottom: 0,
),
child: Text(
'HELLO',
style: TextStyle(
color: Colors.black,
fontSize: 60,
fontWeight: FontWeight.w900,
),
),
),
Container(
// container for the TEXT TEXT
padding: EdgeInsets.only(
top: 130,
left: 20,
right: 0,
bottom: 0,
),
child: Text(
'NEW',
style: TextStyle(
color: Colors.black,
fontSize: 60,
fontWeight: FontWeight.w900,
),
),
),
Container(
// container for the . TEXT
padding: EdgeInsets.only(
top: 130,
left: 160,
right: 0,
bottom: 0,
),
child: Text(
'USER',
style: TextStyle(
color: Colors.teal,
fontSize: 60,
fontWeight: FontWeight.w900,
),
),
),
],
),
),
],
),
);
}
Widget _buildEmail() {
return Container(
padding: EdgeInsets.symmetric(horizontal: 20),
child: TextFormField(
decoration: InputDecoration(
labelText: 'Email',
labelStyle: TextStyle(color: Colors.teal),
),
validator: (value) {
Pattern pattern =
r'^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
RegExp regex = new RegExp(pattern);
if (value.isEmpty) {
return 'Email Required';
} else if (!regex.hasMatch(value)) {
return 'Enter Valid Email';
}
return null;
},
onSaved: (newValue) {
_email = newValue;
},
),
);
}
Widget _buildPassword() {
return Container(
padding: EdgeInsets.only(top: 30, left: 20, right: 20),
child: TextFormField(
decoration: InputDecoration(
labelText: 'Password',
labelStyle: TextStyle(color: Colors.teal),
),
validator: (value) {
if (value.isEmpty) {
return 'Password Required';
} else if (value.length < 6) {
return 'Password too Small';
}
return null;
},
onSaved: (newValue) {
_password = newValue;
},
obscureText: true,
),
);
}
Widget _createSubmitButton() {
return Center(
child: RaisedButton(
color: Colors.teal,
padding: EdgeInsets.symmetric(horizontal: 130, vertical: 10),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
child: Text(
'Sign In',
style: TextStyle(
color: Colors.white,
fontSize: 30,
fontWeight: FontWeight.bold,
),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
dynamic result =
await _auth.signUpWithEmailAndPassword(_email, _password);
if (result == null) {
setState(() {
error = 'Problem with creating account';
});
}
}
},
),
);
}
Widget _createSignInButton() {
// to toggle between between sign up and log in
return FlatButton(
padding: EdgeInsets.only(left: 320),
onPressed: () {
//toggleView;
widget.toggleView();
},
child: Text(
'Sign up',
style: TextStyle(
color: Colors.blue,
fontSize: 20,
),
),
);
}
// this screen is next
return Scaffold(
resizeToAvoidBottomInset: true,
body: SingleChildScrollView(
child: Form(
key: _formKey,
child: Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// build a text that says the word Hello
// build a text that says New
// build a tex that say User
_buildHelloThere(),
// create the text field for email
SizedBox(
height: 40,
),
_buildEmail(),
// create the text field for password
_buildPassword(),
//log in button
_createSignInButton(),
SizedBox(
height: 90,
),
// submit button
_createSubmitButton(),
// error print out
Center(
child: Text(
error,
style: TextStyle(
color: Colors.red,
fontSize: 20,
),
),
),
],
),
),
),
),
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: SignUp(),
);
}
}
Related
I'm making forget password screen for my app and API has integrated in my code. when I click "reset password" button by submitting empty field it running my API code. but I want to run email validation when I submit empty field and click "reset button". how can I do that part in my code. appreciate your help on this.
import 'package:dio/dio.dart';
import 'package:doctor_app/constants/Button.dart';
import 'package:doctor_app/constants/base_api.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
import '../constants/colors.dart';
class ForgetPassword extends StatelessWidget {
const ForgetPassword({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
SystemChrome.setEnabledSystemUIMode(SystemUiMode.leanBack);
return Scaffold(
resizeToAvoidBottomInset: false,
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
height: 20,
),
Text('DOCTOR',
style: TextStyle(
fontFamily: 'Dubai',
fontSize: 30,
color: Color(0xff05ABA3),
fontWeight: FontWeight.w500,
)),
],
),
SizedBox(
height: 90,
),
Row(mainAxisAlignment: MainAxisAlignment.start, children: [
Text('Forgot your password?',
style: TextStyle(
height: 1.2,
fontFamily: 'Dubai',
fontSize: 25,
color: Color(0xff040000),
fontWeight: FontWeight.w500,
)),
]),
// Spacer(
// flex: 1,
// ),
SizedBox(
height: 20,
),
Column(
//mainAxisAlignment: MainAxisAlignment.center,
//crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('Confirm your email and we will send the Instructions ',
style: TextStyle(
height: 1.2,
fontFamily: 'Dubai',
fontSize: 18,
color: Color(0xff707070),
fontWeight: FontWeight.w100,
)),
],
),
SizedBox(
height: 20,
),
ForgetPasswordForm(), //email
SizedBox(
height: 5,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'didnt receive an email?',
style: TextStyle(
height: 1.2,
fontFamily: 'Dubai',
fontSize: 13,
color: Colors.grey,
fontWeight: FontWeight.w500,
),
),
SizedBox(
width: 5,
),
Align(
alignment: Alignment.bottomLeft,
child: InkWell(
onTap: () {
// add action here whatever you want.
},
child: Text('send again ',
style: TextStyle(
height: 1.2,
fontFamily: 'Dubai',
fontSize: 13,
color: Colors.blue,
fontWeight: FontWeight.w500,
))))
],
),
Spacer(
flex: 1,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
color: Color(0xff05ABA3),
),
height: 5,
width: 120,
),
],
),
],
),
),
);
}
}
class ForgetPasswordForm extends StatefulWidget {
const ForgetPasswordForm({Key? key}) : super(key: key);
#override
_ForgetPasswordFormState createState() => _ForgetPasswordFormState();
}
class _ForgetPasswordFormState extends State<ForgetPasswordForm> {
final _formKey = GlobalKey<FormState>();
//String _userName = "";
String email = "";
Future Resetpassword() async {
try {
var response = await Dio().post(BASE_API+'user/forgotpassword', data: {
"email": email,
});
if (response.data["data"] ==
"Please check your email to reset password.") {
Get.snackbar("success", "Email Sent Successfully!");
//Get.to(VideoScreen());
} else {
Get.snackbar("Error", "No Server Found",
backgroundColor: textWhite.withOpacity(0.5),
borderWidth: 1,
borderColor: textGrey,
colorText: textGrey,
icon: Icon(
Icons.error_outline_outlined,
color: heartRed,
size: 30,
));
}
print("res: $response");
} catch (e) {
Get.snackbar("Error", "Something went wrong.Please contact admin",
backgroundColor: textWhite.withOpacity(0.5),
borderWidth: 1,
borderColor: textGrey,
colorText: textGrey,
icon: Icon(
Icons.error_outline_outlined,
color: heartRed,
size: 30,
));
print(e);
}
}
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Form(
child: Container(
key: _formKey,
child: Container(
child: Padding(
padding: const EdgeInsets.all(30.0),
child: Column(children: [
TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
hintText: "Email",
hintStyle: TextStyle(
color: textGrey,
fontFamily: "Dubai",
fontSize: 14)),
validator: (String? Email) {
if (Email != null && Email.isEmpty) {
return "Email can't be empty";
}
return null;
},
onChanged: (String? text) {
email = text!;
print(email);
},
),
SizedBox(
height: 50,
),
Container(
child: GestureDetector(
child: ButtonM("Reset Password"),
onTap: () async {
Resetpassword();
},
),
)
]),
)))));
}
}
Just wrap your ResetPassword() method like below:
if (_formKey.currentState!.validate()) {
Resetpassword();
}
This will check the validation.
Make sure key in attached to Form widget not Container
class ForgetPasswordForm extends StatefulWidget {
const ForgetPasswordForm({Key? key}) : super(key: key);
#override
_ForgetPasswordFormState createState() => _ForgetPasswordFormState();
}
class _ForgetPasswordFormState extends State<ForgetPasswordForm> {
final _formKey = GlobalKey<FormState>();
String email = "";
Future Resetpassword() async {
print("123");
}
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Form(
key: _formKey,
autovalidateMode: AutovalidateMode.disabled,
child: Container(
child: Container(
child: Padding(
padding: const EdgeInsets.all(30.0),
child: Column(children: [
TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: const InputDecoration(
hintText: "Email",
hintStyle: TextStyle(
color: Colors.grey,
fontFamily: "Dubai",
fontSize: 14)),
validator: (String? Email) {
if (Email != null && Email.isEmpty) {
return "Email can't be empty";
}
return null;
},
onChanged: (String? text) {
email = text!;
print(email);
},
),
SizedBox(
height: 50,
),
Container(
child: TextButton(
child: Text("Reset Password"),
onPressed: () async {
if (_formKey.currentState!.validate()) {
Resetpassword();
}
},
),
)
]),
)))));
}
}
Add variable
final GlobalKey<FormState> keys = GlobalKey<FormState>();
validate like that
if (_keys.currentState!.validate()) {
Resetpassword();
}
Hi in the below code when I enter my mobile number, password and then click on the login button nothing is happening. My API working in Postman is not working here.
When I press the button it is not working, Entering a valid mobile number and password are not working.
Can anyone help me to find where I did any mistakes?
Login_screen.dart:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:sample_live/home_screen.dart';
import 'package:sample_live/model/login_model.dart';
import 'package:sample_live/splash_screen.dart';
import 'package:sample_live/login_otp.dart';
import 'ProgressHUD.dart';
import 'api/api_service.dart';
class LoginScreen extends StatefulWidget {
String name;
LoginScreen({this.name});
#override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final mobileController = TextEditingController();
final passwordController = TextEditingController();
LoginRequestModel requestModel;
bool isApiCallProcess = false;
GlobalKey<FormState> globalFormKey = GlobalKey<FormState>();
LoginRequestModel loginRequestModel;
final scaffoldKey = GlobalKey<ScaffoldState>();
#override
void initState(){
super.initState();
requestModel=new LoginRequestModel();
}
#override
Widget build(BuildContext context) {
return ProgressHUD(
child: _uiSetup(context),
inAsyncCall: isApiCallProcess,
opacity: 0.3,
);
}
Widget _uiSetup(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Login", style: TextStyle(color: Colors.white)),
centerTitle: true,
),
body:
Stack(
children: [
Padding(
padding: EdgeInsets.all(30),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset('assets/images/hand.png',),
Padding(
padding: EdgeInsets.all(10),
child: Text("Welcome Doctor! ",
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold
),),
),
Padding(
padding: EdgeInsets.all(10),
),
Text("Let's treat everyone great",
style: TextStyle(
color: Colors.black,
fontSize: 15,
),),
Padding(
padding: EdgeInsets.all(10),
),
TextFormField(
minLines: 1,
keyboardType: TextInputType.number,
onSaved: (input) => loginRequestModel.Mobile = input,
textInputAction: TextInputAction.next,
decoration: InputDecoration(
labelText: "Enter Mobile No.",
hintText: "Enter Mobile No.",
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(16.0)))),
),
SizedBox(
height: 10,
),
TextFormField(
onSaved: (input) =>
loginRequestModel.Password = input,
validator: (input) =>
input.length < 3
? "Password should be more than 3 characters"
: null,
minLines: 1,
obscureText: true,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
decoration: InputDecoration(
labelText: "Password",
hintText: "Password",
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(16.0)))),
),
SizedBox(
height: 10,
),
Container(
width: double.infinity,
padding: EdgeInsets.symmetric(vertical: 20, horizontal: 20),
margin: EdgeInsets.symmetric(vertical: 20, horizontal: 20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30)
),
child: RaisedButton(
color: Color(0xFF0769AA),
onPressed: () {
if (validateAndSave()) {
print(loginRequestModel.toJson());
setState(() {
isApiCallProcess = true;
});
APIService apiService = new APIService();
apiService.login(loginRequestModel).then((value) {
if (value != null) {
setState(() {
isApiCallProcess = false;
});
if (value.Status.isNotEmpty) {
final snackBar = SnackBar(
content: Text("Login Successful"));
scaffoldKey.currentState
.showSnackBar(snackBar);
} else {
final snackBar =
SnackBar(content: Text(value.Message));
scaffoldKey.currentState
// ignore: deprecated_member_use
.showSnackBar(snackBar);
}
}
});
}
},
child: Text(
"Login",
style: TextStyle(color: Colors.white),
),
),
),
SizedBox(
height: 10,
),
Text("Or",
style: TextStyle(
color: Colors.black,
fontSize: 15,
),),
Container(
width: double.infinity,
child: FlatButton(
color: Color(0xFF0769AA),
onPressed: () {
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(
builder: (context) => LoginOtp("Welcome")),
(route) => false);
},
child: Text(
"Login With OTP",
style: TextStyle(color: Colors.white),
),
),
),
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
GestureDetector(
onTap: () {
// write your function
Navigator.push(
context,
MaterialPageRoute(
builder: (contex) => SplashScreen()));
},
child: Text(
"Forgot Password",
style: TextStyle(
color: Colors.blue,
fontSize: 16,
fontWeight: FontWeight.bold,
)
)),
],
),
],
),
),
Container(
alignment: Alignment.bottomCenter,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
"By logging in or signing up, you agree to the",
textAlign: TextAlign.end,
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
),
Text(
"Privacy Policy & Terms and Condition",
textAlign: TextAlign.end,
style: TextStyle(
color: Colors.blue,
fontSize: 12,
),
),
],
)
)
]),
);
}
bool validateAndSave() {
final form = globalFormKey.currentState;
if (form.validate()) {
form.save();
return true;
}
return false;
}
}
I've been trying to accept user input in an extracted TextFormField method(Name, contact and email) and then save them to my firestore database using TextEditingController.
Here lies the case after accepting the input, the name and email controller always displays the same input. After saving, even for test purposes, the database always shows that only null values have been returned from the controllers...
Please help me solve this problem...
Snippet of the code:
class Profile extends StatefulWidget {
final String email;
Profile({Key key, this.email}) : super(key: key);
get user => AuthService();
#override
_ProfileState createState() => _ProfileState(email);
}
class _ProfileState extends State<Profile> {
String email;
String contain;
_ProfileState(this.email);
bool showPhone = false;
//Text editing controller
final TextEditingController _emailController = TextEditingController();
final TextEditingController _phoneController = TextEditingController();
final TextEditingController _nameController = TextEditingController();
// initState
#override
void initState() {
super.initState();
_emailController.addListener(() {
final String text = _emailController.text;
_emailController.value = _emailController.value.copyWith(
text: text,
selection:
TextSelection(baseOffset: text.length, extentOffset: text.length),
composing: TextRange.empty,
);
});
_phoneController.addListener(() {
final String contact = _phoneController.text;
_phoneController.value = _phoneController.value.copyWith(
text: contact,
selection: TextSelection(
baseOffset: contact.length,
extentOffset: contact.length,
),
composing: TextRange.empty,
);
});
_nameController.addListener(() {
final String contact = _nameController.text;
_nameController.value = _nameController.value.copyWith(
text: contact,
selection: TextSelection(
baseOffset: contact.length,
extentOffset: contact.length,
),
composing: TextRange.empty,
);
});
}
#override
void dispose() {
// Clean up the controller when the widget is removed from the
// widget tree.
_emailController.dispose();
_phoneController.dispose();
_nameController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
final FirebaseAuth _auth = FirebaseAuth.instance;
bool loading = false;
final _formKey = GlobalKey<FormState>();
final doc = Database();
final ThemeData themeData = Theme.of(context);
String name, email, contact;
return loading
? Loading()
: SafeArea(
child: StreamBuilder<UserData>(
stream: Database(uid: doc.uid).userData,
builder: (context, snapshot) {
if (snapshot.hasData) {
UserData userData = snapshot.data;
return Scaffold(
appBar: AppBar(
backgroundColor: Aqua,
elevation: 1,
title: Text(
'Edit Profile Info',
style: themeData.textTheme.headline1.copyWith(
color: White,
fontSize: 22,
letterSpacing: 0.75,
),
),
),
body: new Container(
height: window.physicalSize.height * 0.85,
padding: const EdgeInsets.only(
left: 16,
right: 16,
top: 25,
),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
new Center(
child: new Stack(
children: [
addVertical(20),
Container(
width: 190,
height: 190,
decoration: BoxDecoration(
border: Border.all(
width: 5,
color: Theme.of(context)
.scaffoldBackgroundColor,
),
boxShadow: [
BoxShadow(
blurRadius: 15,
spreadRadius: 5,
color: Cyan.withOpacity(0.5),
offset: Offset(0, 15),
),
],
shape: BoxShape.circle,
image: DecorationImage(
image: AssetImage(
"assets/images/IMG2.jpg"),
fit: BoxFit.cover,
),
),
),
Positioned(
bottom: 0,
right: 0,
child: Container(
height: 55,
width: 55,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
width: 5,
color: Theme.of(context)
.scaffoldBackgroundColor,
),
color: Cyan,
),
child: IconButton(
icon: Icon(
Icons.edit,
color: Dark_Blue,
),
onPressed:
() {}, // change profile picture
),
),
),
],
),
),
addVertical(30),
Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.only(
top: 25, left: 35, right: 35, bottom: 10),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
buildTextFormField(
"Full Name",
userData.fname ??
"Enter Full Name here...",
false,
false ?? null,
),
addVertical(15),
buildTextFormField(
"Contact",
userData.contact ?? "020 *** ****",
true,
false ?? null,
),
addVertical(15),
buildTextFormField(
"E-mail",
userData.email ?? "emaple123#gmail.com",
false,
true ?? null,
),
],
),
),
),
),
addVertical(35),
Padding(
padding: const EdgeInsets.only(
left: 35, right: 35, top: 25),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
primary: White,
),
onPressed: () {
Navigator.pop(context);
},
child: Text(
"CANCEL",
style: themeData.textTheme.bodyText1
.copyWith(
letterSpacing: 1.25,
fontWeight: FontWeight.bold,
fontSize: 18,
color: Mid_Blue,
),
),
),
ElevatedButton(
onPressed: () async {
if (_formKey.currentState.validate()) {
setState(() => loading = true);
dynamic result =
await _auth.currentUser;
// User person = result.user;
if (result != null) {
await Database(uid: doc.uid)
.updateData(
"$name",
"$email",
"$contact",
);
Toast.show(
"Your details have been successfully updated!",
context,
duration: Toast.LENGTH_LONG,
gravity: Toast.BOTTOM,
);
setState(() => loading = false);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Homepage()));
} else {
Toast.show(
"Please try again later",
context,
gravity: Toast.BOTTOM,
duration: Toast.LENGTH_LONG,
);
}
}
},
style: ElevatedButton.styleFrom(
elevation: 2,
primary: Colors.green[300],
shape: new RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
), //!elevatedButton background
),
child: Text(
"SAVE",
style: TextStyle(
fontSize: 18,
letterSpacing: 2.2,
color: White,
),
),
),
],
),
),
],
//),
),
),
),
);
} else {
return Loading();
}
},
),
);
}
Widget buildTextFormField(
String labelText,
String placeholder,
bool isPhone,
bool isEmail,
) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 10),
child: TextField(
onSubmitted: isPhone || isEmail
? (value) {
value = _phoneController.toString() != null
? _emailController.toString() != null
: _nameController;
}
: null,
controller: isEmail || isPhone
? (value) {
value = _emailController.toString() != null
? _nameController.toString() != null
: _phoneController;
}
: _emailController,
obscureText: isPhone ? showPhone : false,
decoration: InputDecoration(
suffixIcon: isPhone
? IconButton(
onPressed: () => setState(() => showPhone = !showPhone),
icon: Icon(
Icons.remove_red_eye,
color: Red,
),
)
: null, //!This makes the icon appear only for the password field
contentPadding: EdgeInsets.only(bottom: 3),
labelText: labelText,
labelStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Aqua,
),
floatingLabelBehavior: FloatingLabelBehavior.always,
hintText: placeholder,
hintStyle: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Cyan,
),
),
keyboardType:
isPhone ? TextInputType.phone : TextInputType.emailAddress,
),
);
}
}
This is the function that builds name textField
buildTextFormField(
"Full Name",
userData.fname ?? "Enter Full Name here...",
false, // isPhone
false ?? null, // isEmail
),
From here we can see that isPhone = false; isEmail = false;
This is the function for the and controller in TextFormField:
controller: isEmail || isPhone
? (value) {
value = _emailController.toString() != null
? _nameController.toString() != null
: _phoneController;
}
: _emailController,
Since isEmail and isPhone are both false, it returns _emailController for name Textfield. So name is being updated on email textfield.
The function for onSubmitted() returns null if isEmail & isPhone are both false. Therefore, for name field, it will return null as the value (probably why you are getting null in the database).
I have tried to better organise the code below:
class MyHomePage extends StatefulWidget {
final String email;
MyHomePage({Key key, this.email}) : super(key: key);
get user => AuthService();
#override
_MyHomePageState createState() => _MyHomePageState(email);
}
class _MyHomePageState extends State<MyHomePage> {
String email;
// not used in this class
String contain;
_MyHomePageState(this.email);
bool showPhone = false;
//Text editing controller
final TextEditingController _emailController = TextEditingController();
final TextEditingController _phoneController = TextEditingController();
final TextEditingController _nameController = TextEditingController();
#override
void dispose() {
// Clean up the controller when the widget is removed from the
// widget tree.
_emailController.dispose();
_phoneController.dispose();
_nameController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
final FirebaseAuth _auth = FirebaseAuth.instance;
bool loading = false;
final _formKey = GlobalKey<FormState>();
final doc = Database();
final ThemeData themeData = Theme.of(context);
return loading
? Loading()
: SafeArea(
child: StreamBuilder<UserData>(
stream: Database(uid: doc.uid).userData,
builder: (context, snapshot) {
if (snapshot.hasData) {
UserData userData = snapshot.data;
_emailController.text = userData.email;
_phoneController.text = userData.phone;
_nameController.text = userData.name;
return Scaffold(
appBar: AppBar(
backgroundColor: Aqua,
elevation: 1,
title: Text(
'Edit Profile Info',
style: themeData.textTheme.headline1.copyWith(
color: White,
fontSize: 22,
letterSpacing: 0.75,
),
),
),
body: new Container(
height: window.physicalSize.height * 0.85,
padding: const EdgeInsets.only(
left: 16,
right: 16,
top: 25,
),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
new Center(
child: new Stack(
children: [
addVertical(20),
Container(
width: 190,
height: 190,
decoration: BoxDecoration(
border: Border.all(
width: 5,
color: Theme.of(context)
.scaffoldBackgroundColor,
),
boxShadow: [
BoxShadow(
blurRadius: 15,
spreadRadius: 5,
color: Cyan.withOpacity(0.5),
offset: Offset(0, 15),
),
],
shape: BoxShape.circle,
image: DecorationImage(
image: AssetImage(
"assets/images/IMG2.jpg"),
fit: BoxFit.cover,
),
),
),
Positioned(
bottom: 0,
right: 0,
child: Container(
height: 55,
width: 55,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
width: 5,
color: Theme.of(context)
.scaffoldBackgroundColor,
),
color: Cyan,
),
child: IconButton(
icon: Icon(
Icons.edit,
color: Dark_Blue,
),
onPressed:
() {}, // change profile picture
),
),
),
],
),
),
addVertical(30),
Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.only(
top: 25, left: 35, right: 35, bottom: 10),
child: SingleChildScrollView(
child: Column(
children: <Widget>[
buildTextFormField(
"Full Name",
"Enter Full Name here...",
false,
_nameController,
),
addVertical(15),
buildTextFormField(
"Contact",
"020 *** ****",
true,
_phoneController,
),
addVertical(15),
buildTextFormField(
"E-mail",
"example123#gmail.com",
false,
_nameController,
),
],
),
),
),
),
addVertical(35),
Padding(
padding: const EdgeInsets.only(
left: 35, right: 35, top: 25),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
ElevatedButton(
style: ElevatedButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
primary: White,
),
onPressed: () {
Navigator.pop(context);
},
child: Text(
"CANCEL",
style: themeData.textTheme.bodyText1
.copyWith(
letterSpacing: 1.25,
fontWeight: FontWeight.bold,
fontSize: 18,
color: Mid_Blue,
),
),
),
ElevatedButton(
onPressed: () async {
if (_formKey.currentState.validate()) {
setState(() => loading = true);
dynamic result =
await _auth.currentUser;
// User person = result.user;
if (result != null) {
await Database(uid: doc.uid)
.updateData(
_nameController.text,
_emailController.text,
_phoneController.text,
);
Toast.show(
"Your details have been successfully updated!",
context,
duration: Toast.LENGTH_LONG,
gravity: Toast.BOTTOM,
);
setState(() => loading = false);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
Homepage()));
} else {
Toast.show(
"Please try again later",
context,
gravity: Toast.BOTTOM,
duration: Toast.LENGTH_LONG,
);
}
}
},
style: ElevatedButton.styleFrom(
elevation: 2,
primary: Colors.green[300],
shape: new RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
), //!elevatedButton background
),
child: Text(
"SAVE",
style: TextStyle(
fontSize: 18,
letterSpacing: 2.2,
color: White,
),
),
),
],
),
),
],
//),
),
),
),
);
} else {
return Loading();
}
},
),
);
}
Widget buildTextFormField(
String labelText,
String placeholder,
bool isPhone,
TextEditingController controller,
) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 15, horizontal: 10),
child: TextField(
// onSubmitted: isPhone || isEmail
// ? (value) {
// value = _phoneController.toString() != null
// ? _emailController.toString() != null
// : _nameController;
// }
// : null,
controller: controller,
obscureText: isPhone ? showPhone : false,
decoration: InputDecoration(
suffixIcon: isPhone
? IconButton(
onPressed: () => setState(() => showPhone = !showPhone),
icon: Icon(
Icons.remove_red_eye,
color: Red,
),
)
: null, //!This makes the icon appear only for the password field
contentPadding: EdgeInsets.only(bottom: 3),
labelText: labelText,
labelStyle: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Aqua,
),
floatingLabelBehavior: FloatingLabelBehavior.always,
hintText: placeholder,
hintStyle: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Cyan,
),
),
keyboardType:
isPhone ? TextInputType.phone : TextInputType.emailAddress,
),
);
}
}
I have stored all articles in cloud firestore and now im searching a article from cloud firestore.
Search is working fine but when i tap on a article to go on detail screen to read more. i m getting this error : type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'DocumentSnapshot'
this is my search screen :
class SearchService {
searchByName(String searchField) {
return FirebaseFirestore.instance
.collection('articles')
.where('searchKey',
isEqualTo: searchField.substring(0, 1).toUpperCase())
.get();
}
}
class SearchScreen extends StatefulWidget {
#override
_SearchScreenState createState() => new _SearchScreenState();
}
class _SearchScreenState extends State<SearchScreen> {
var queryResultSet = [];
var tempSearchStore = [];
initiateSearch(value) {
if (value.length == 0) {
setState(() {
queryResultSet = [];
tempSearchStore = [];
});
}
if (queryResultSet.length == 0 && value.length == 1) {
SearchService().searchByName(value).then((QuerySnapshot docs) {
for (int i = 0; i < docs.docs.length; ++i) {
queryResultSet.add(docs.docs[i].data());
setState(() {
tempSearchStore.add(queryResultSet[i]);
});
}
});
} else {
queryResultSet.forEach((element) {
if (element['title'].toLowerCase().contains(value.toLowerCase()) ==
true) {
if (element['title'].toLowerCase().atIndex(value.toLowerCase()) ==
0) {
setState(() {
tempSearchStore.add(element);
});
}
}
});
}
if (tempSearchStore.length == 0 && value.length > 1) {
setState(() {});
}
}
#override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: Colors.white,
appBar: new AppBar(
iconTheme: IconThemeData(color: CustomColors.blackColor),
title: TextField(
onChanged: (val) {
initiateSearch(val);
},
decoration: InputDecoration(
hintText: 'Search here',
hintStyle: TextStyle(
color: CustomColors.greyColor,
fontWeight: FontWeight.bold,
),
border: InputBorder.none,
),
),
),
body: ListView(
padding: EdgeInsets.only(left: 10.0, right: 10.0),
shrinkWrap: true,
children: tempSearchStore.map((element) {
return SearchResults(
data: element,
);
}).toList(),
),
);
}
}
this my search item:
class SearchResults extends StatelessWidget {
final data;
const SearchResults({this.data});
#override
Widget build(BuildContext context) {
var readTime = readingTime(data['desc']);
return InkWell(
onTap: () {
Get.to(
DetailScreen(
articles: data,
),
);
},
child: Container(
height: Get.mediaQuery.size.height * 0.24,
width: Get.mediaQuery.size.width * 0.8,
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 20),
decoration: BoxDecoration(
color: Colors.grey.withOpacity(0.1),
borderRadius: BorderRadius.circular(20),
),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
constraints: BoxConstraints(
maxWidth: Get.mediaQuery.size.width * 0.65,
),
child: Text(
data['title'],
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 22,
color: CustomColors.blackColor,
fontWeight: FontWeight.w600,
),
),
),
Image.network(
data['imageUrl'],
height: 100,
width: 100,
fit: BoxFit.cover,
),
],
),
],
),
),
);
}
}
this is my detail screen to view full article:
class DetailScreen extends StatelessWidget {
final DocumentSnapshot articles;
final ArticlesController articlesController = Get.find<ArticlesController>();
DetailScreen({#required this.articles});
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 0,
iconTheme: IconThemeData(color: CustomColors.blackColor),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.only(top: 40),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
toBeginningOfSentenceCase(
articles.data()['title'],
),
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: CustomColors.blackColor,
),
),
SizedBox(
height: 10,
),
Padding(
padding: const EdgeInsets.only(
top: 15, right: 30, left: 30, bottom: 15),
child: SelectableText(
articles.data()['desc'],
toolbarOptions: ToolbarOptions(copy: true, selectAll: true),
style: TextStyle(
fontSize: 20,
letterSpacing: 1,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
),
],
),
),
),
);
}
}
docs.docs[i] is a DocumentSnapshot
But docs.docs[i].data() is a Map<String, dynamic>
You have add lists (queryResultList and other) as Map but detailscreen field is DocumentSnapshot.
I have two files...Workout.dart and Submit.dart. In Workout.dart I have variables: name, sets, rep, pmg, and smg. The use will input things for the variables and then once they click submit, a new page will open displaying the data. However, I don't know how to carry over that data. I'm new to Flutter and Dart, Please help!
Workout.dart
import 'package:flutter/material.dart';
import 'package:gyminprogress/Submit.dart';
class This extends StatefulWidget{
#override
Workout createState() => Workout();
}
class Workout extends State<This> {
String name , sets , rep , pmg , smg ;
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueGrey,
appBar: AppBar(
title: Text('Create Workouts'),
centerTitle: true,
),
body: Container(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
TextField(
decoration: InputDecoration(
hintText: 'Exercise Name'
),
style: TextStyle(color:Colors.white),
onChanged: (value){
setState(() {
name = value;
});
},
),
SizedBox(
height: 40.0,
),
TextField(
decoration: InputDecoration(
hintText: 'Primary Muscle Group'
),
style: TextStyle(color:Colors.white),
onChanged: (value){
setState(() {
pmg = value;
});
},
),
SizedBox(
height: 40.0,
),
TextField(
decoration: InputDecoration(
hintText: 'Secondary Muscle Group'
),
style: TextStyle(color:Colors.white),
onChanged: (value){
setState(() {
smg = value;
});
},
),SizedBox(
height: 40.0,
),
TextField(
decoration: InputDecoration(
hintText: 'Reps'
),
style: TextStyle(color:Colors.white),
onChanged: (value){
setState(() {
rep = value;
});
},
),
SizedBox(
height: 40.0,
),
TextField(
decoration: InputDecoration(
hintText: 'Sets'
),
style: TextStyle(color:Colors.white),
onChanged: (value){
setState(() {
sets = value;
});
},
),
Expanded(
child: Container(
child: Column(mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
RaisedButton(
color: Colors.cyan[200],
padding: EdgeInsets.symmetric(
horizontal: 80.0,
vertical: 20.0
,),
child: Text('Submit',style: TextStyle(
color: Colors.black,fontWeight: FontWeight.w200
),) ,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Submit (
)),
);
},
),
]
),]),)
)
]
)
),
),
);
}
}
Submit.dart
import 'package:flutter/material.dart';
import 'package:gyminprogress/Workout.dart';
class Submit extends StatefulWidget{
#override
Enter createState() => Enter();
}
class Enter extends State<Submit> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueGrey,
appBar: AppBar(
title: Text('Create Workouts'),
centerTitle: true,
),
body: Container(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: <Widget>[
Text('Exercise Name : ${Workout.name}',
style: TextStyle(fontSize: 20.0,color: Colors.white, fontWeight: FontWeight.w200),),
Text('Primary Muscle Group : ${Workout.pmg} ',
style: TextStyle(fontSize: 20.0,color: Colors.white, fontWeight: FontWeight.w200),),
Text('Secondary Muscle Group : ${Workout.smg} ',
style: TextStyle(fontSize: 20.0,color: Colors.white, fontWeight: FontWeight.w200),),
Text('Reps : ${Workout.rep}',
style: TextStyle(fontSize: 20.0,color: Colors.white, fontWeight: FontWeight.w200),),
Text('Sets : ${Workout.sets}',
style: TextStyle(fontSize: 20.0,color: Colors.white, fontWeight: FontWeight.w200),),
]
)
)
)
);
}
}
To pass data from one widget to another you have to do two things,
Create a constructor of widget having data which it will accept,
Pass that data while calling it from another widget.
here is the code which solves your problem:
workout.dart
import "package:flutter/material.dart";
import './submit.dart';
class Workout extends StatefulWidget {
#override
_WorkoutState createState() => _WorkoutState();
}
class _WorkoutState extends State<Workout> {
String name, sets, rep, pmg, smg;
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Builder(
builder: (context) => Scaffold(
appBar: AppBar(
title: Text('Create Workouts'),
centerTitle: true,
),
body: Container(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Scaffold(
body: Column(children: <Widget>[
TextField(
decoration: InputDecoration(hintText: 'Exercise Name'),
style: TextStyle(color: Colors.black),
onChanged: (value) {
setState(() {
name = value;
});
},
),
SizedBox(
height: 40.0,
),
TextField(
decoration:
InputDecoration(hintText: 'Primary Muscle Group'),
style: TextStyle(color: Colors.black),
onChanged: (value) {
setState(() {
pmg = value;
});
},
),
SizedBox(
height: 40.0,
),
TextField(
decoration:
InputDecoration(hintText: 'Secondary Muscle Group'),
style: TextStyle(color: Colors.black),
onChanged: (value) {
setState(() {
smg = value;
});
},
),
SizedBox(
height: 40.0,
),
TextField(
decoration: InputDecoration(hintText: 'Reps'),
style: TextStyle(color: Colors.black),
onChanged: (value) {
setState(() {
rep = value;
});
},
),
SizedBox(
height: 40.0,
),
TextField(
decoration: InputDecoration(hintText: 'Sets'),
style: TextStyle(color: Colors.black),
onChanged: (value) {
setState(() {
sets = value;
});
},
),
Expanded(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
RaisedButton(
color: Colors.cyan[200],
padding: EdgeInsets.symmetric(
horizontal: 80.0,
vertical: 20.0,
),
child: Text(
'Submit',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w600),
),
onPressed: () {
//String name, sets, rep, pmg, smg;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Submit(
name: name,
sets: sets,
rep: rep,
pmg: pmg,
smg: smg,
),
),
);
},
),
]),
]),
))
]))),
),
),
),
);
}
}
submit.dart
import "package:flutter/material.dart";
class Submit extends StatelessWidget {
final String name, sets, rep, pmg, smg;
const Submit({
Key key,
this.name = "",
this.sets = "",
this.rep = "",
this.pmg = "",
this.smg = "",
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.blueGrey,
appBar: AppBar(
title: Text('Create Workouts'),
centerTitle: true,
),
body: Container(
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(children: <Widget>[
Text(
'Exercise Name : ${name}',
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
fontWeight: FontWeight.w200),
),
Text(
'Primary Muscle Group : ${pmg} ',
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
fontWeight: FontWeight.w200),
),
Text(
'Secondary Muscle Group : ${smg} ',
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
fontWeight: FontWeight.w200),
),
Text(
'Reps : ${rep}',
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
fontWeight: FontWeight.w200),
),
Text(
'Sets : ${sets}',
style: TextStyle(
fontSize: 20.0,
color: Colors.white,
fontWeight: FontWeight.w200),
),
]))));
}
}
Output:
New Updated code
Output:
You can pass data in the navigator.
class Workout extends ....> {
String name;
Person(this.name);
}
// Navigate to second screen with data
Navigator.push(context, new MaterialPageRoute(builder: (context) => new SecondScreenWithData(person: new Person("Vishal"))));
Then in the second screen
class SecondScreenWithData extends StatelessWidget {
// Declare a field that holds the Person data
final Person person;
// In the constructor, require a Person
SecondScreenWithData({Key key, #required this.person}) : super(key: key);
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Second Screen With Data"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
// Display passed data from first screen
Text("name: ${person.name}"),
RaisedButton(
child: Text("Back to previous screen"),
onPressed: () {
// Navigate back to first screen when tapped!
Navigator.pop(context);
}
),
],
)
),
);
}