StreamProvider is not responding to changed value of stream - flutter

I am making a flutter application where i need to register into firebase.
First I have SignInPage() which uses Navigator to redirect to ResidentRegister().Here is the form for registering into the application. The problem is the ResidentRegister() page is not getting redirected to HomeScreen() upon successful Authentication of the user. The user is properly registered into the firebase and HomeScreen() appears after hotrestart of the application. I have used StreamProvider for the purpose which should listen to a stream of type 'Resident' which is my User data model based on whether it is null or not in the Wrapper() class. In the 'Wrapper' class, the stream is getting 'instance of resident'(when I print the value of resident variable), but the else block is not getting executed. This is probably happening due to usage of Navigator as when I remove the first screen that is SignInPage(), the ResidentRegister() screen is successfully getting redirected to HomeScreen(). I don't know why this happens as I have wrapped the MaterialApp to StreamProvider widget.
Any help would be appreciated
Thanks!
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return StreamProvider<Resident>(
create: (_)=> AuthService().resident,
child: Consumer<Resident>(
builder: (context, resident, _)
{
return MaterialApp(
home: (user != null) ? HomeScreen() : SignInPage(),
);
},
),
);
}
}
class SignInPage extends StatelessWidget {
SignInPage({this.title});
final String title;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('JNMCH eLogBook'),
centerTitle: true,
),
body: SizedBox.expand(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('Sign In',
style: TextStyle(
color: Colors.teal,
fontWeight: FontWeight.w300,
fontSize: 65,
),),
SizedBox(height: 35,),
CustomButton(text: 'Sign In as a Resident', onPressed: ()=> Navigator.pushNamed(context, '/residentRegister')),
SizedBox(height:8.0),
CustomButton(text: 'Sign In as a Mentor', onPressed: () => Navigator.pushNamed(context,'/mentorSignIn')),
],
),
),
);
}
}
class ResidentRegister extends StatefulWidget {
#override
_ResidentRegisterState createState() => _ResidentRegisterState();
}
class _ResidentRegisterState extends State<ResidentRegister> {
final AuthService _auth = AuthService();
final _formKey = GlobalKey<FormState>();
String _email;
String _password;
String _confirmPassword;
String _error = '';
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
title: Text('Register as a Resident'),
),
body: SingleChildScrollView(
child: Stack(
children: <Widget>[
Center(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 80.0, horizontal: 40.0),
child: Card(
color: Colors.white,
elevation: 8.0,
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
SizedBox(height: 20,),
Text('Register',
style: TextStyle(
color: Colors.teal,
fontWeight: FontWeight.w300,
fontSize: 65,
),
),
SizedBox(height: 35,),
TextFormField(
validator: (val) => val.isEmpty ? 'Enter an email' : null,
decoration: InputDecoration(
hintText: 'Email'
),
onChanged: (value) {
setState(() {
_email = value;
});
},
),
SizedBox(height: 20,),
TextFormField(
validator: (val) => val.length < 6 ? 'Enter a password 6+ char long' : null,
decoration: InputDecoration(
hintText: 'Password'
),
obscureText: true,
onChanged: (value) {
setState(() {
_password = value;
});
},
),
SizedBox(height: 20,),
TextFormField(
validator: (val) => val!=_password ? 'Confirm Password must be same as password' : null,
decoration: InputDecoration(
hintText: 'Confirm Password'
),
obscureText: true,
onChanged: (value) {
setState(() {
_confirmPassword = value;
});
},
),
SizedBox(height: 20,),
Padding(
padding: const EdgeInsets.all(0),
child: ButtonTheme(
minWidth: 150,
height: 50,
child: RaisedButton(onPressed: () async {
if(_formKey.currentState.validate()){
dynamic result = await _auth.register( _email,_password);
if(result == null){
setState(() {
_error = 'Please supply a valid email';
});
}
}
},
color: Colors.teal,
child:
Text(
'Submit',
style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 20,),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(28.0),
side: BorderSide(color: Colors.teal[100]),
),
),
),
),
SizedBox(height: 20,),
Text(_error, style: TextStyle(
fontSize: 14.0,
color: Colors.red,
),),
SizedBox(height: 20,),
FlatButton(
color: Colors.white,
textColor: Colors.grey[600],
disabledColor: Colors.black,
disabledTextColor: Colors.black,
padding: EdgeInsets.all(8.0),
splashColor: Colors.teal,
onPressed: () {
Navigator.pop(context);
},
child: Text(
"Already have an account? Sign In!",
style: TextStyle(fontSize: 16.0),
),
)
],
),
),
),
),
),
],
),
),
);
}
}
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final AuthService _auth = AuthService();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Home Page'),
actions: <Widget> [
FlatButton.icon(
onPressed: ()async {
await _auth.signOut();
},
icon: Icon(Icons.person,color: Colors.white,),
label: Text('Sign Out', style: TextStyle(color: Colors.white),)),
],
),
);
}
}
class AuthService{
final FirebaseAuth _auth = FirebaseAuth.instance;
// create resident user object based on Firebase User
Resident _residentFromFirebaseUser(FirebaseUser user){
return user!=null ? Resident(uid: user.uid) : null;
}
//auth change user stream
Stream<Resident> get resident {
return _auth.onAuthStateChanged
.map(_residentFromFirebaseUser);
}
//register with email and password
Future register(String email, String password) async{
try{
AuthResult result = await _auth.createUserWithEmailAndPassword(email: email, password: password);
FirebaseUser user = result.user;
print(user);
return _residentFromFirebaseUser(user);
}catch(e){
print(e.toString());
return null;
}
}
//sign out
Future signOut() async{
try{
return await _auth.signOut();
}catch(e){
print(e.toString());
return null;
}
}
}
class Resident{
final String uid;
Resident({ this.uid });
}

I believe you're using StreamProvider incorrectly. It shouldn't be:
StreamProvider<Resident>.value(value: ...)
Instead, try using:
StreamProvider<Resident>(
create: (_) => AuthService().resident,
child: Consumer<Resident>(
builder: (context, resident, _) {
// TODO: return home page or sign in page based on data
},
),
);
That should subscribe to the stream and rebuild on new events.

Related

Flutter: Submit TextFormField on Enter

I'm working on a desktop application for Windows with Flutter. I want to listen to keyboard keys. I made a Login page and it has two TextFormFields, (one for Username and the other for Password).
When I press the 'enter' key on the keyboard, I want the form to be submitted as I pressed on 'Login' button. So if I pressed the 'enter' key from either Username or Password text fields, I want the app to act exactly as if I pressed the 'Login' Button.
Here is a picture of the Login Page:
--> Login Page
Here is the code of Login Page:
import 'package:flutter/material.dart';
import '../../api/services/login_services.dart';
import '../../api/models/login_models.dart';
import '../../constants/constant_methods.dart';
import '../main_page/main_screen.dart';
import '../../constants/constant_variables.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
TextEditingController usernameController = TextEditingController();
TextEditingController passwordController = TextEditingController();
late LoginRequestModel loginRequestModel;
bool isUsernameEmpty = false;
bool isPasswordEmpty = false;
bool secure = true;
bool notSecure = false;
bool isLoading = false;
#override
void initState() {
super.initState();
loginRequestModel = LoginRequestModel(
usernameController.text,
passwordController.text,
);
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
decoration: const BoxDecoration(
gradient: loginPageGradient,
),
child: Center(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
'assets/images/cloud_soft_logo.png',
height: 90,
),
const SizedBox(height: 15),
Text(
'Hoomy\'s Real Estate',
style: Theme.of(context).textTheme.headline4,
),
const SizedBox(height: 20),
Container(
width: 310,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: borderRadius(10.0),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const SizedBox(height: 20),
Text(
'Welcome',
style: Theme.of(context)
.textTheme
.headline6!
.copyWith(
fontWeight: FontWeight.w600,
foreground: Paint()..shader = linearGradient),
),
Text(
'Please Log in to Your Account',
style: Theme.of(context).textTheme.headline2,
),
const SizedBox(height: 10),
loginTextField("Username", "Username can't be empty",
usernameController),
loginTextField("Password", "Password can't be empty",
passwordController),
forgetPasswordButton(),
loginButton(context),
const SizedBox(height: 40),
],
),
),
],
),
),
),
),
),
);
}
Widget loginTextField(
String labelText,
String errorText,
TextEditingController controller,
) {
return SizedBox(
width: 250,
child: TextFormField(
decoration: InputDecoration(
labelText: labelText,
errorText: labelText == "Username"
? isUsernameEmpty
? errorText
: null
: isPasswordEmpty
? errorText
: null,
suffixIcon: labelText == "Username"
? IconButton(
onPressed: () {}, icon: const Icon(Icons.person, size: 20))
: IconButton(
onPressed: () {
setState(() {
secure = !secure;
});
},
icon: Icon(
secure ? Icons.visibility_off : Icons.visibility,
size: 20,
),
)),
obscureText: labelText == "Username" ? notSecure : secure,
controller: controller,
),
);
}
Padding forgetPasswordButton() {
return Padding(
padding: const EdgeInsets.all(20).copyWith(right: 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Theme(
data: ThemeData(splashColor: Colors.transparent),
child: TextButton(
child: const Text('Forget Password'),
onPressed: () {},
),
),
],
),
);
}
DecoratedBox loginButton(BuildContext context) {
return DecoratedBox(
decoration: BoxDecoration(
borderRadius: borderRadius(50.0),
gradient: loginButtonGradient,
),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.transparent,
fixedSize: const Size(250, 50),
shape: RoundedRectangleBorder(
borderRadius: borderRadius(50.0),
)),
child: isLoading
? CircularProgressIndicator(
color: Colors.blue[800],
backgroundColor: Colors.grey,
)
: const Text('Login'),
onPressed: () {
setState(() {
usernameController.text.isEmpty
? isUsernameEmpty = true
: isUsernameEmpty = false;
passwordController.text.isEmpty
? isPasswordEmpty = true
: isPasswordEmpty = false;
});
setState(() {
isLoading = true;
});
LoginService.login(usernameController.text, passwordController.text)
.then((response) {
setState(() {
isLoading = false;
});
if (response) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const MainScreen(),
),
);
} else if (!response &&
usernameController.text.isNotEmpty &&
passwordController.text.isNotEmpty) {
showErrorDialog(context, "Invalid Username or Password!");
}
});
}),
);
}
Future<dynamic> showErrorDialog(BuildContext context, String dialogContent) {
return showDialog(
context: context,
builder: (BuildContext context) {
return Center(
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: SizedBox(
width: 350,
child: AlertDialog(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(borderRadius: borderRadius(10.0)),
title: Text("Error",
style: Theme.of(context)
.textTheme
.bodyText1!
.copyWith(color: Colors.red)),
content: Text(dialogContent,
style: Theme.of(context)
.textTheme
.headline2!
.copyWith(color: Colors.black87)),
actions: <Widget>[
TextButton(
child: Text("OK",
style: Theme.of(context)
.textTheme
.bodyText1!
.copyWith(color: Colors.blue)),
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
),
),
);
},
);
}
}
Add the field onFieldSubmitted and a FormKey:
// Widget attribute
final _formKey = GlobalKey<FormState>();
// Widget method: build()
Form(
key: _formKey,
child:
TextFormField(
onFieldSubmitted: (value) {
print('ENTER pressed');
// Will trigger validation for ALL fields in Form.
// All your TextFormFields (email, password) share
// the SAME Form and thus the SAME _formKey.
if (_formKey.currentState!.validate()) {
print('ALL FIELDS ARE VALID, GO ON ...');
}
}
)
)
Docs
https://api.flutter.dev/flutter/material/TextFormField-class.html

!_debugLocked is not true when making changes

I'm getting this error when i make any changes to my app, i need to re run my app to get rid of this error. I tried to make some changes to my navigation but nothing changes. I also i'm searching for hours on the google to find something useful but i can't find anything to make it work.
Note: I'm beginner on Flutter development
Main.dart:
import 'dart:io';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:tasker/screens/HomeScreen.dart';
import 'package:progress_dialog/progress_dialog.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: LoginDemo(),
);
}
}
class LoginDemo extends StatefulWidget {
#override
_LoginDemoState createState() => _LoginDemoState();
}
class _LoginDemoState extends State<LoginDemo> {
late ProgressDialog progressDialog;
FirebaseAuth auth = FirebaseAuth.instance;
String email = "";
String password = "";
#override
Widget build(BuildContext context) {
progressDialog = ProgressDialog(context);
Future<String> getCurrentUserEmail() async {
FirebaseUser user = await auth.currentUser();
String userEmail = user.email.toString();
return userEmail;
}
// Navigate user to HomeScreen if already singed in
if (auth.currentUser() != null) {
Future.delayed(Duration(seconds: 3));
Navigator.pushReplacement(context, new MaterialPageRoute(builder: (context) => HomeScreen(userEmail: '',)));
}
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Login"),
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
child: Container(
width: 200,
height: 150,
/*
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(50.0)),*/
child: Image(
image: NetworkImage('https://cdn-icons-png.flaticon.com/512/1055/1055672.png'),
)),
),
),
Padding(
padding: const EdgeInsets.only(left:15.0, right: 15.0, top:30, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
onChanged: (value) {
setState(() {
this.email = value;
});
},
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
hintText: 'Enter email'),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
onChanged: (value) {
setState(() {
this.password = value;
});
},
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
hintText: 'Enter password'),
),
),
TextButton(
onPressed: (){
// open reset password screen
},
child: Text(
'Forgot Password?',
style: TextStyle(color: Colors.blue, fontSize: 15),
),
),
Container(
height: 50,
width: 250,
decoration: BoxDecoration(
color: Colors.blue, borderRadius: BorderRadius.circular(20)),
child: TextButton (
onPressed: () async {
progressDialog.show();
try {
AuthResult authResult = await FirebaseAuth.instance.signInWithEmailAndPassword(
email: email.toString(),
password: password.toString()
);
FirebaseUser user = authResult.user;
if (user == null) {
progressDialog.hide();
print("logged in");
await Future.delayed(Duration(seconds: 3));
Navigator.pushReplacement(context, new MaterialPageRoute(builder: (context) => HomeScreen(userEmail: '',)));
}
} catch (e) {
print(e.toString());
}
},
child: Text(
'Login',
style: TextStyle(color: Colors.white, fontSize: 25),
),
),
),
SizedBox(
height: 130,
),
TextButton(
onPressed: (){
// open reset password screen
},
child: Text(
'New user? Sign up!',
style: TextStyle(color: Colors.black, fontSize: 20, fontWeight: FontWeight.bold),
),
),
],
),
),
floatingActionButton: FloatingActionButton(onPressed: () {
},),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat
);
}
}
I found multiple issues with the code, but the one which caused the debugLocked error was using future directly inside the build method, you either put the future in a FutureBuilder or run outside the build method.
Here is the code fixed:
import 'dart:io';
import 'package:tasker/screens/HomeScreen.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_progress_dialog/flutter_progress_dialog.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: LoginDemo(),
);
}
}
class LoginDemo extends StatefulWidget {
#override
_LoginDemoState createState() => _LoginDemoState();
}
class _LoginDemoState extends State<LoginDemo> {
late ProgressDialog progressDialog;
FirebaseAuth auth = FirebaseAuth.instance;
String email = "";
String password = "";
Future<String>? getCurrentUserEmail() async {
User user = await auth.currentUser!;
String userEmail = user.email.toString();
return userEmail;
}
// Navigate user to HomeScreen if already singed in
#override
void initState() {
progressDialog = ProgressDialog(
child: Container(
child: Text('Loading'),
),
);
// TODO: implement initState
super.initState();
}
Future<void>? checkUserLoggedIn() async {
if (auth.currentUser != null) {
await Future.delayed(Duration(seconds: 3));
Navigator.pushReplacement(
context,
new MaterialPageRoute(
builder: (context) => HomeScreen(
userEmail: '',
)));
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Login"),
),
body: ProgressDialog(
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
child: Container(
width: 200,
height: 150,
child: Image(
image: NetworkImage(
'https://cdn-icons-png.flaticon.com/512/1055/1055672.png'),
)),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 30, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
onChanged: (value) {
setState(() {
this.email = value;
});
},
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
hintText: 'Enter email'),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
onChanged: (value) {
setState(() {
this.password = value;
});
},
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
hintText: 'Enter password'),
),
),
TextButton(
onPressed: () {
// open reset password screen
},
child: Text(
'Forgot Password?',
style: TextStyle(color: Colors.blue, fontSize: 15),
),
),
Container(
height: 50,
width: 250,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(20)),
child: TextButton(
onPressed: () async {
showProgressDialog();
try {
UserCredential authResult = await FirebaseAuth.instance
.signInWithEmailAndPassword(
email: email.toString(),
password: password.toString());
User user = authResult.user!;
if (user == null) {
dismissProgressDialog();
print("logged in");
await Future.delayed(Duration(seconds: 3));
Navigator.pushReplacement(
context,
new MaterialPageRoute(
builder: (context) => HomeScreen(
userEmail: '',
)));
}
} catch (e) {
print(e.toString());
}
},
child: Text(
'Login',
style: TextStyle(color: Colors.white, fontSize: 25),
),
),
),
SizedBox(
height: 130,
),
TextButton(
onPressed: () {
// open reset password screen
},
child: Text(
'New user? Sign up!',
style: TextStyle(
color: Colors.black,
fontSize: 20,
fontWeight: FontWeight.bold),
),
),
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {},
),
floatingActionButtonLocation: FloatingActionButtonLocation.endFloat);
}
}

flutter: how to autofill password in login form

I am trying when user check the checkbox it will autofill the password when user login again, i tried autofillhints in password textfield and wrap the widgets in AutofillGroup, but it is not working, when i login once and login again i am required to enter the password again.
and i am using api for fetching username and password.
here is my login code
class Login extends StatefulWidget {
Login({Key key, this.title}) : super(key: key);
final String title;
#override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
var name,password,token;
bool _passwordVisibilty;
void initState(){
_passwordVisibilty=false;
_formatDateTime();
}
String formattedDate;
String _formatDateTime() {
var now = new DateTime.now();
var formatter = new DateFormat('yyyy-MM-dd');
formattedDate = formatter.format(now);
print(formattedDate);
}
//svar localhostUrl="http://10.0.2.2:8000/login";
var herokuUrl="https://attendance-demo.herokuapp.com/login";
bool isSameuser = true;
final String username='';
final String email='';
final String designation='';
Future login() async {
try{
Dio dio=new Dio();
var data={
'username': user.username,
'password': user.password,
'date':formattedDate
};
await dio
.post(localhostUrlLogin,data: json.encode(data))
.then((onResponse) async {
//edited code here
SharedPreferences myPrefs=await SharedPreferences.getInstance();
String name=(onResponse.data['User']['username']);
String password=(onResponse.data['User']['password']);
if(name==""&&password==""){
myPrefs.setString('username', name);
myPrefs.setString('password', password);
}
else{
user.username=name;
user.password=password;
}
});}catch(e){
print("error "+e.toString());
showAlertDialog(BuildContext context) {
// Create button
Widget okButton = FlatButton(
child: Text("OK"),
onPressed: () {
Navigator.of(context).pop();
},
);
// Create AlertDialog
AlertDialog alert = AlertDialog(
title: Text("Error",style: TextStyle(fontWeight: FontWeight.bold)),
content: Text("Invalid name or password.",style: TextStyle(fontSize: 17),),
actions: [
okButton,
],
);
// show the dialog
showDialog(
context: context,
builder: (BuildContext context) {
return alert;
},
);
}
User user = User('', '');
//--------------------------
passwordtext(){
return TextFieldContainer(
child: TextFormField(
controller: TextEditingController(text: user.password),
autofillHints: [AutofillHints.password], //here is used autfodillhints
onEditingComplete: ()=>TextInput.finishAutofillContext(), //and i used this too
decoration: InputDecoration(
border: InputBorder.none,
icon: Icon(Icons.lock,color: Colors.blue,),
suffixIcon: GestureDetector(
onTap: () {
setState(() {
_passwordVisibilty = !_passwordVisibilty;
});
},
child: Icon(
_passwordVisibilty ? Icons.visibility : Icons.visibility_off,
),
),
labelText: 'Password'),
obscureText: !_passwordVisibilty,
onChanged: (value){
user.password=value;
},
),
);
}
return Scaffold(
body: SingleChildScrollView(
child: AutofillGroup(
child: Center(
child: Container(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(36.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(
height: 155.0,
width: 200.0,
child: Image.asset(
"assets/image/company_logo.png",
fit: BoxFit.contain,
),
),
SizedBox(height: 50.0),
RoundedInputField(
labelText: "Username",icon: Icons.email,fontsize: textFontSize,
controller: TextEditingController(text: user.username),
onChanged: (value){
user.username=value;
},
),
SizedBox(height: 15.0),
passwordtext(),
SizedBox(
height: 0.0,
),
Align(
alignment: Alignment.centerLeft,
child:Row(children: <Widget>[
Checkbox(
checkColor: Colors.greenAccent,
activeColor: Colors.blue,
value: isSameuser,
onChanged: (bool newValue) {
if(newValue!=null){
setState(() {
isSameuser = newValue;
});
}},
),
Text("Save password?")
],)
),
SizedBox(
height: 23.0,
),
FlatButton(
color: Colors.blue[500],
textColor: Colors.white,
padding: EdgeInsets.all(15.0),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(buttonRoundRadius)),
child: Row(
children:<Widget>[
Expanded(child:
Text("Login",
textAlign: TextAlign.center,
style: TextStyle(fontSize: textFontSize),),)
,]),
onPressed: () {
login();
}
)
]),
),
),
),
))
);
}
}
Try this:
Use SharedPrefrences.
check if username and password is null, if it is null then store the username and password in the preferences.
if it is not null set the value of the textController to the values in the sharedPrefrences.

How to navigate from login to home page with Firebase flutter

In the welcome screen, I have two button which is login and register. For the first time, when i try to login to the login screen, it did not navigate to the Home Page. For the second try, I want to login again, it can't back to the login page (stuck at Welcome Screen). Can anyone help me? Thank you
Welcome Screen Code:
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
class WelcomeScreen extends StatefulWidget {
#override
_WelcomeScreenState createState() => _WelcomeScreenState();
}
class _WelcomeScreenState extends State<WelcomeScreen> {
final FirebaseAuth _auth = FirebaseAuth.instance;
navigateToLogin() async {
Navigator.pushReplacementNamed(context, "Login");
}
navigateToRegister() async {
Navigator.pushReplacementNamed(context, "SignUp");
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Column(
children: <Widget>[
SizedBox(height: 35.0),
Container(
height: 400,
child: Image(
image: AssetImage("assets/girlsave.png"),
fit: BoxFit.contain,
),
),
SizedBox(height: 20),
RichText(
text: TextSpan(
text: 'Welcome to ',
style: TextStyle(
fontSize: 25.0,
fontWeight: FontWeight.bold,
color: Colors.orange),
children: <TextSpan>[
TextSpan(
text: 'MONGER!',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.orange))
])),
SizedBox(height: 10.0),
Text(
'Your Personal Money Tracker',
style: TextStyle(color: Colors.black),
),
SizedBox(height: 30.0),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
padding: EdgeInsets.only(left: 30, right: 30),
onPressed: navigateToLogin,
child: Text(
'LOGIN',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
color: Colors.orange),
SizedBox(width: 20.0),
RaisedButton(
padding: EdgeInsets.only(left: 30, right: 30),
onPressed: navigateToRegister,
child: Text(
'REGISTER',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
color: Colors.orange),
],
),
SizedBox(height: 20.0),
],
),
),
);
}
}
Login Page Code:
import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:monger_app/WelcomeScreen/signup.dart';
class LoginPage extends StatefulWidget {
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final FirebaseAuth _auth = FirebaseAuth.instance;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String _email, _password;
checkAuthentification() async {
_auth.authStateChanges().listen((user) {
if (user != null) {
print(user);
Navigator.pushReplacementNamed(context, "/");
}
});
}
#override
void initState() {
super.initState();
this.checkAuthentification();
}
login() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
try {
await _auth.signInWithEmailAndPassword(
email: _email, password: _password);
} catch (e) {
showError(e.message);
print(e);
}
}
}
showError(String errormessage) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('ERROR'),
content: Text(errormessage),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK'))
],
);
});
}
navigateToSignUp() async {
Navigator.push(context, MaterialPageRoute(builder: (context) => SignUpPage()));
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0,
brightness: Brightness.light,
backgroundColor: Colors.white,
leading: IconButton(
onPressed: (){
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back_ios,
size: 20,
color: Colors.black,),
),
),
body: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
Container(
height: 400,
child: Image(
image: AssetImage("assets/girlsave.png"),
fit: BoxFit.contain,
),
),
Container(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
Container(
child: TextFormField(
validator: (input) {
if (input.isEmpty) return 'Enter Email';
},
decoration: InputDecoration(
labelText: 'Email',
prefixIcon: Icon(Icons.email)),
onSaved: (input) => _email = input),
),
Container(
child: TextFormField(
validator: (input) {
if (input.length < 6)
return 'Provide Minimum 6 Character';
},
decoration: InputDecoration(
labelText: 'Password',
prefixIcon: Icon(Icons.lock),
),
obscureText: true,
onSaved: (input) => _password = input),
),
SizedBox(height: 20),
RaisedButton(
padding: EdgeInsets.fromLTRB(70, 10, 70, 10),
onPressed: login,
child: Text('LOGIN',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold)),
color: Colors.orange,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
)
],
),
),
),
GestureDetector(
child: Text('Create an Account?'),
onTap: navigateToSignUp,
)
],
),
),
));
}
}
Sign Up code:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
class SignUpPage extends StatefulWidget {
#override
_SignUpPageState createState() => _SignUpPageState();
}
class _SignUpPageState extends State<SignUpPage> {
FirebaseAuth _auth = FirebaseAuth.instance;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
String _username, _email, _password;
checkAuthentication() async {
_auth.authStateChanges().listen((user) async {
if (user != null) {
Navigator.pushReplacementNamed(context, "/");
}
});
}
#override
void initState() {
super.initState();
this.checkAuthentication();
}
signUp() async {
if (_formKey.currentState.validate()) {
_formKey.currentState.save();
try {
UserCredential user = await _auth.createUserWithEmailAndPassword(
email: _email, password: _password);
if (user != null) {
// UserUpdateInfo updateuser = UserUpdateInfo();
// updateuser.displayName = _name;
// user.updateProfile(updateuser);
await _auth.currentUser.updateProfile(displayName: _username);
// await Navigator.pushReplacementNamed(context,"/") ;
}
} catch (e) {
showError(e.message);
print(e);
}
}
}
showError(String errormessage) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text('ERROR'),
content: Text(errormessage),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('OK'))
],
);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0,
brightness: Brightness.light,
backgroundColor: Colors.white,
leading: IconButton(
onPressed: (){
Navigator.pop(context);
},
icon: Icon(Icons.arrow_back_ios,
size: 20,
color: Colors.black,),
),
),
body: SingleChildScrollView(
child: Container(
child: Column(
children: <Widget>[
Container(
height: 400,
child: Image(
image: AssetImage("assets/girlsave.png"),
fit: BoxFit.contain,
),
),
Container(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
Container(
child: TextFormField(
validator: (input) {
if (input.isEmpty) return 'Enter Username';
},
decoration: InputDecoration(
labelText: 'Username',
prefixIcon: Icon(Icons.person),
),
onSaved: (input) => _username = input),
),
Container(
child: TextFormField(
validator: (input) {
if (input.isEmpty) return 'Enter Email';
},
decoration: InputDecoration(
labelText: 'Email',
prefixIcon: Icon(Icons.email)),
onSaved: (input) => _email = input),
),
Container(
child: TextFormField(
validator: (input) {
if (input.length < 6)
return 'Provide Minimum 6 Character';
},
decoration: InputDecoration(
labelText: 'Password',
prefixIcon: Icon(Icons.lock),
),
obscureText: true,
onSaved: (input) => _password = input),
),
SizedBox(height: 20),
RaisedButton(
padding: EdgeInsets.fromLTRB(70, 10, 70, 10),
onPressed: signUp,
child: Text('SignUp',
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold)),
color: Colors.orange,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
),
)
],
),
),
),
],
),
),
));
}
}
Main Code:
import 'package:flutter/material.dart';
import 'package:monger_app/WelcomeScreen/login.dart';
import 'package:monger_app/WelcomeScreen/signup.dart';
import 'package:monger_app/WelcomeScreen/welcome_screen.dart';
import 'package:monger_app/page/root.dart';
import 'package:monger_app/theme/colors.dart';
import 'package:firebase_core/firebase_core.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
primaryColor: primary
),
debugShowCheckedModeBanner: false,
home:
WelcomeScreen(),
routes: <String,WidgetBuilder>{
"Login" : (BuildContext context)=>LoginPage(),
"SignUp":(BuildContext context)=>SignUpPage(),
"start":(BuildContext context)=>Root(),
},
);
}
}
HomePage Code
import 'package:flutter/material.dart';
import 'package:flutter_icons/flutter_icons.dart';
import 'package:monger_app/page/setting.dart';
import 'package:monger_app/theme/colors.dart';
import 'package:animated_bottom_navigation_bar/animated_bottom_navigation_bar.dart';
import 'package:monger_app/page/transaction.dart';
import 'package:monger_app/page/statistics.dart';
import 'package:monger_app/page/account.dart';
import 'package:monger_app/page/record.dart';
import 'package:firebase_auth/firebase_auth.dart';
class Root extends StatefulWidget {
#override
_RootState createState() => _RootState();
}
class _RootState extends State<Root> {
final FirebaseAuth _auth = FirebaseAuth.instance;
User user;
bool isloggedin = false;
checkAuthentification() async {
_auth.authStateChanges().listen((user) {
if (user == null) {
Navigator.of(context).pushReplacementNamed("start");
}
});
}
int pageIndex = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: getBody(),
bottomNavigationBar: getFooter(),
floatingActionButton: FloatingActionButton(
onPressed: (){
setTabs(4);
},
child: Icon(Icons.add, size: 25),
backgroundColor: primary,
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
Widget getBody(){
return IndexedStack(
index: pageIndex,
children: [
Transaction(),
Statistics(),
Account(),
Settings(),
Record()
],
);
}
Widget getFooter(){
List<IconData> iconItems = [
Ionicons.md_bookmarks,
Ionicons.md_stats,
Ionicons.md_wallet,
Ionicons.ios_settings,
];
return AnimatedBottomNavigationBar(
activeColor: primary,
splashColor: secondary,
inactiveColor: Colors.black.withOpacity(0.5),
icons: iconItems,
activeIndex: pageIndex,
gapLocation: GapLocation.center,
notchSmoothness: NotchSmoothness.softEdge,
leftCornerRadius: 10,
iconSize: 25,
rightCornerRadius: 10,
onTap: (index) {
setTabs(index);
});
}
setTabs(index) {
setState(() {
pageIndex = index;
});
}
}
You have this code:
Navigator.pushReplacementNamed(context, "/");
but you do not have the named route "/" registered.
From your code, your Home Page is registered as "start".
So you should update the name of the route to "start" and that should work.
Your updated code should be as below:
Navigator.pushReplacementNamed(context, "start");

Bottom Navigation bar disappears on sign in, but returns when I go to another page and back?

I am trying to create an app that will show the user a generic homepage with products and give them the option to navigate to an account page where, if they are not signed in they will be shown a sign in/sign up page or if they have signed in, they will be shown their profile.
I have managed to get the sign in/sign out part working, but when I sign in and navigate to the profile page, my bottom navigation bar disappears. However, when I navigate to another page and back, it reappears.
Here is my home.dart file which controls navigation for my app:
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
PageController _pageController = PageController();
List<Widget> _screens = [HomePage(), InboxPage(), AccountController()];
int _selectedIndex = 0;
void _onPageChanged(int index) {
setState(() {
_selectedIndex = index;
});
}
void _onItemTapped(int selectedIndex) {
_pageController.jumpToPage(selectedIndex);
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: _pageController,
children: _screens,
onPageChanged: _onPageChanged,
physics: NeverScrollableScrollPhysics(),
),
bottomNavigationBar: BottomNavigationBar(onTap: _onItemTapped, items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
color: _selectedIndex == 0 ? Colors.blueAccent : Colors.grey,
),
title: Text(
'Home',
style: TextStyle(
color: _selectedIndex == 0 ? Colors.blueAccent : Colors.grey,
),
),
),
BottomNavigationBarItem(
icon: Icon(
Icons.email,
color: _selectedIndex == 1 ? Colors.blueAccent : Colors.grey,
),
title: Text(
'Inbox',
style: TextStyle(
color: _selectedIndex == 1 ? Colors.blueAccent : Colors.grey,
),
),
),
BottomNavigationBarItem(
icon: Icon(
Icons.account_circle,
color: _selectedIndex == 2 ? Colors.blueAccent : Colors.grey,
),
title: Text(
'Account',
style: TextStyle(
color: _selectedIndex == 2 ? Colors.blueAccent : Colors.grey,
),
),
),
]),
);
}
}
My accountcontroller.dart code which helps determine whether a user is logged in or not:
class AccountController extends StatelessWidget {
#override
Widget build(BuildContext context) {
final AuthService auth = Provider.of(context).auth;
return StreamBuilder(
stream: auth.onAuthStateChanged,
builder: (context, AsyncSnapshot<String> snapshot) {
if (snapshot.connectionState == ConnectionState.active) {
final bool signedIn = snapshot.hasData;
return signedIn ? ProfileView() : SignUpPage();
}
return CircularProgressIndicator();
});
}
}
My profileview.dart:
class ProfileView extends StatefulWidget {
#override
_ProfileViewState createState() => _ProfileViewState();
}
class _ProfileViewState extends State<ProfileView> {
#override
Widget build(BuildContext context) {
return
Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(80),
child: MainAppBar(
text: 'Account',
)),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Text('Account Page'),
showSignOut(context),
goToHomepage(context),
],
),
),
);
}
}
Widget showSignOut(context) {
return RaisedButton(
child: Text('Sign Out'),
onPressed: () async {
try {
await Provider.of(context).auth.signOut();
Navigator.pushNamed(context, '/homepage');
print('Signed Out');
} catch (e) {
print(e);
}
});
}
Widget goToHomepage(context) {
return RaisedButton(
child: Text('Go to homepage'),
onPressed: () async {
try {
Navigator.pushNamed(context, '/homepage');
} catch (e) {
print(e);
}
});
}
And finally my signup.dart file which contains my sign up/sign in code:
enum AuthFormType { signIn, signUp }
class SignUpPage extends StatefulWidget {
final AuthFormType authFormType;
SignUpPage({Key key, this.authFormType}) : super(key: key);
#override
_SignUpPageState createState() =>
_SignUpPageState(authFormType: this.authFormType);
}
class _SignUpPageState extends State<SignUpPage> {
AuthFormType authFormType;
_SignUpPageState({this.authFormType});
final formKey = GlobalKey<FormState>();
String _firstName,
_lastName,
_email,
_confirmEmail,
_password,
_confirmPassword,
_dateOfBirth;
bool validate() {
final form = formKey.currentState;
form.save();
if (form.validate()) {
form.save();
print('true');
return true;
} else {
print('false');
return false;
}
}
void switchFormState(String state) {
formKey.currentState.reset();
if (state == 'signIn') {
setState(() {
authFormType = AuthFormType.signIn;
});
} else {
setState(() {
authFormType = AuthFormType.signUp;
});
}
}
void submit() async {
final CollectionReference userCollection =
Firestore.instance.collection('UserData');
if (validate()) {
try {
final auth = Provider.of(context).auth;
if (authFormType == AuthFormType.signIn) {
String uid = await auth.signInWithEmailAndPassword(_email, _password);
print("Signed In with ID $uid");
Navigator.of(context).pushReplacementNamed('/home');
} else {
String uid = await auth.createUserWithEmailAndPassword(
_email,
_password,
);
userCollection.document(uid).setData({
'First Name': _firstName,
'Last Name': _lastName,
'Date of Birth': _dateOfBirth
});
print("Signed up with New ID $uid");
Navigator.of(context).pushReplacementNamed('/home');
}
} catch (e) {
print(e);
}
}
}
DateTime selectedDate = DateTime.now();
TextEditingController _date = new TextEditingController();
Future<Null> _selectDate(BuildContext context) async {
DateFormat formatter =
DateFormat('dd/MM/yyyy'); //specifies day/month/year format
final DateTime picked = await showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(1901, 1),
builder: (BuildContext context, Widget child) {
return Theme(
data: ThemeData.light().copyWith(
colorScheme: ColorScheme.light(
primary: kPrimaryColor,
onPrimary: Colors.black,),
buttonTheme: ButtonThemeData(
colorScheme: Theme.of(context)
.colorScheme
.copyWith(primary: Colors.black),
),
),
child: child,
);
},
lastDate: DateTime(2100));
if (picked != null && picked != selectedDate)
setState(() {
selectedDate = picked;
_date.value = TextEditingValue(
text: formatter.format(
picked)); //Use formatter to format selected date and assign to text field
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(80),
child: MainAppBar(
text: buildAppBarText(),
)),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Center(
child: Container(
child: Column(
children: <Widget>[
Align(
child: Text(buildTitleText(), style: AppBarTextStyle),
),
Container(
padding: EdgeInsets.only(top: 10),
),
Padding(
padding: const EdgeInsets.all(20.0),
child: Form(
key: formKey,
child: Column(
children: buildInputs() + buildSwitchText(),
)),
),
],
),
),
),
),
));
}
buildHeaderText() {
String _headerText;
if (authFormType == AuthFormType.signUp) {
_headerText = "Don't have an account?";
} else {
_headerText = "Already have an account?";
}
return _headerText;
}
List<Widget> buildInputs() {
List<Widget> textFields = [];
DateFormat dateFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
if (authFormType == AuthFormType.signIn) {
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Email'),
validator: SignInEmailValidator.validate,
onSaved: (value) => _email = value.trim()));
textFields.add(SizedBox(
height: 15,
));
textFields.add(
TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Password'),
obscureText: true,
validator: SignInPasswordValidator.validate,
onSaved: (value) => _password = value.trim(),
),
);
} else {
textFields.clear();
//if we're in the sign up state, add name
// add email & password
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('First Name'),
validator: NameValidator.validate,
onSaved: (value) => _firstName = value,
));
textFields.add(SizedBox(
height: 15,
));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Last Name'),
onSaved: (value) => _lastName = value,
validator: NameValidator.validate,
));
textFields.add(SizedBox(
height: 15,
));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Email Address'),
onSaved: (value) => _email = value.trim(),
validator: SignInEmailValidator.validate,
));
textFields.add(SizedBox(
height: 15,
));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Confirm Email Address'),
onSaved: (value) => _confirmEmail = value,
validator: (confirmation) {
return confirmation == _email
? null
: "Confirm Email Address should match email address";
},
));
textFields.add(SizedBox(
height: 15,
));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Password'),
obscureText: true,
onSaved: (value) => _password = value,
));
textFields.add(SizedBox(
height: 15,
));
textFields.add(TextFormField(
style: TextStyle(
fontSize: 12.0,
),
decoration: buildSignUpInputDecoration('Confirm Password'),
onSaved: (value) => _confirmPassword = value,
validator: (confirmation) {
return confirmation == _password
? null
: "Confirm Password should match password";
}));
textFields.add(SizedBox(
height: 15,
));
textFields.add(GestureDetector(
onTap: () => _selectDate(context),
child: AbsorbPointer(
child: TextFormField(
style: TextStyle(fontSize: 12.0),
controller: _date,
keyboardType: TextInputType.datetime,
decoration: InputDecoration(
isDense: true,
fillColor: Colors.white,
hintText: 'Date of Birth',
filled: true,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(width: 0.0),
),
contentPadding:
const EdgeInsets.only(left: 14.0, bottom: 10.0, top: 10.0),
),
onSaved: (value) => _dateOfBirth = value,
),
),
));
textFields.add(SizedBox(
height: 15,
));
}
return textFields;
}
List<Widget> buildSwitchText() {
String _switchButtonTextPart1, _switchButtonTextPart2, _newFormState;
if (authFormType == AuthFormType.signIn) {
_switchButtonTextPart1 = "Haven't got an account? ";
_switchButtonTextPart2 = 'Sign Up';
_newFormState = 'signUp';
} else {
_switchButtonTextPart1 = 'Already have an account? ';
_switchButtonTextPart2 = 'Sign In';
_newFormState = 'signIn';
}
return [
SizedBox(height: 5.0),
Container(
width: MediaQuery.of(context).size.height * 0.7,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5.0),
),
color: kPrimaryColor,
textColor: Colors.black,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
buildTitleText(),
style: TextStyle(fontFamily: FontNameDefault, fontSize: 15.0),
),
),
onPressed: submit),
),
SizedBox(
height: 5.0,
),
RichText(
text: TextSpan(
style: TextStyle(
fontFamily: FontNameDefault,
color: Colors.black,
fontSize: 12.0,
),
children: <TextSpan>[
TextSpan(text: _switchButtonTextPart1),
TextSpan(
text: _switchButtonTextPart2,
style: TextStyle(
decoration: TextDecoration.underline,
color: Colors.black,
fontSize: 12.0),
recognizer: TapGestureRecognizer()
..onTap = () {
switchFormState(_newFormState);
})
]),
),
];
}
String buildAppBarText() {
String _switchAppBarHeader;
if (authFormType == AuthFormType.signIn) {
_switchAppBarHeader = "Already have an account?";
} else {
_switchAppBarHeader = "Don't have an account?";
}
return _switchAppBarHeader;
}
String buildTitleText() {
String _switchTextHeader;
if (authFormType == AuthFormType.signIn) {
_switchTextHeader = "Sign In";
} else {
_switchTextHeader = "Sign Up";
}
return _switchTextHeader;
}
}
InputDecoration buildSignUpInputDecoration(String hint) {
return InputDecoration(
isDense: true,
fillColor: Colors.white,
hintText: hint,
filled: true,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(width: 0.0),
),
contentPadding: const EdgeInsets.only(left: 14.0, bottom: 10.0, top: 10.0),
);
}
Any ideas?
The HomePage(), InboxPage() and AccountController() are in your home-widget, which contains the bottomNavigationBar.
Your profile and signup pages are different pages with its own scaffold.
You have to create one central "index" widget wich holds every sub-page and the navigationbar.