I am new to programming can someone help me what's the problem here, I was doing a login page and this happens - flutter

If password and username is same, I want to print 'username and password is same' statement in the terminal .But it is only printing the second statement 'username and password does not match even if username and password is same or not . I don't understand why this happened somebody help, I am new here' ( NB : problem is inside the function named checkLogin)
class ScreenLogin extends StatefulWidget {
ScreenLogin({Key? key}) : super(key: key);
#override
State<ScreenLogin> createState() => _ScreenLoginState();
}
class _ScreenLoginState extends State<ScreenLogin> {
final _usernameController = TextEditingController();
final _passwordController = TextEditingController();
bool _isDataMatched = false;
final _formkey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: Form(
key: _formkey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
TextFormField(
controller: _usernameController,
decoration: const InputDecoration(
border: OutlineInputBorder(), hintText: 'Username'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'value is empty';
} else {
return null;
}
},
),
const SizedBox(
height: 20,
),
TextFormField(
controller: _passwordController,
obscureText: true,
decoration: const InputDecoration(
border: OutlineInputBorder(), hintText: 'Password'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'value is empty';
} else {
return null;
}
}),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Visibility(
visible: _isDataMatched,
child: Text(
'Username and password does not match',
style: TextStyle(color: Colors.red),
),
),
ElevatedButton.icon(
onPressed: () {
if (_formkey.currentState!.validate()) {
checkLogin(context);
} else {
print('Data Empty');
}
},
icon: const Icon(Icons.check),
label: const Text('Login ')),
],
)
],
),
),
),
));
}
void checkLogin(BuildContext context) {
final _username = _usernameController;
final _password = _passwordController;
if (_password == _username) {
print('Username and password is matching');
} else {
print('Username and password does not match');
}
}
}

To get text, you need to use .text on controller.
_usernameController.text;
void checkLogin(BuildContext context) {
final _username = _usernameController.text;
final _password = _passwordController.text;
if (_password == _username) {
print('Username and password is matching');
} else {
print('Username and password does not match');
}
}

In login check you should do this:
void checkLogin(BuildContext context) {
final _username = _usernameController.text;
final _password = _passwordController.text;
if (_password == _username) {
print('Username and password is matching');
} else {
print('Username and password does not match');
}
}

Related

I'm making a authentication login form then I face this error

I'm making authentication login form and want to connect submitAuthForm Function to the AuthForm. That's why I pass reference in the AuthForm. I am beginner. Please help me to solve this problem (The argument type void Function(String, String, String, bool) can't be assigned to the parameter type void Function(String, String, String, bool)
Thanks.
class AuthScreen extends StatefulWidget {
#override
_AuthScreenState createState() => _AuthScreenState();
}
class _AuthScreenState extends State<AuthScreen> {
void _submitAuthForm(
String email,
String password,
String username,
bool isLogin) {
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).primaryColor,
body: Authform(_submitAuthForm,)/*( The argument type 'void Function(String, String, String, bool)' can't be assigned to the parameter type 'Void Function(String, String, String, bool)'.*/)
);
}
}
class Authform extends StatefulWidget {
Authform(this.submitFN);
final Void Function(
String email, String password, String username, bool isLogin) submitFN;
#override
_AuthformState createState() => _AuthformState();
}
class _AuthformState extends State<Authform> {
final _formKey = GlobalKey<FormState>();
var _isLogin = true;
var _userEmail;
var _userName;
var _userPassword;
void _trySubmit() {
final isValid = _formKey.currentState!.validate();
FocusScope.of(context).unfocus();
if (isValid) {
_formKey.currentState!.save();
widget.submitFN(_userEmail,_userPassword,_userName,_isLogin);
}
}
#override
Widget build(BuildContext context) {
return Center(
child: Card(
margin: EdgeInsets.all(20),
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
key: ValueKey('email'),
validator: (value) {
if (value!.isEmpty || !value.contains('#')) {
return 'please enter valid email address';
}
return null;
},
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
icon: Icon(
Icons.mail,
color: Colors.orange,
),
labelText: 'Email Addess'),
onSaved: (value) {
_userEmail = value;
},
),
if (!_isLogin)
TextFormField(
key: ValueKey('username'),
validator: (value) {
if (value!.isEmpty || value.length < 4) {
return 'Username is short enter atleast 4 characters ';
}
},
decoration: InputDecoration(
icon: Icon(
Icons.person,
color: Colors.orange,
),
labelText: 'Username'),
onSaved: (value) {
_userName = value;
},
),
TextFormField(
key: ValueKey('password'),
validator: (value) {
if (value!.isEmpty || value.length < 7) {
return 'Password must be atleast 7 characters long';
}
return null;
},
decoration: InputDecoration(
icon: Icon(
Icons.lock,
color: Colors.orange,
),
labelText: 'password',
),
obscureText: true,
onSaved: (value) {
_userPassword = value;
},
),
SizedBox(
height: 12,
),
ElevatedButton(
onPressed: _trySubmit,
child: Text(_isLogin ? 'Login' : 'Signup'),
style: ElevatedButton.styleFrom(onPrimary: Colors.white),
),
TextButton(
onPressed: () {
setState(() {
_isLogin = !_isLogin;
});
},
child: Text(_isLogin
? 'Create new account'
: 'I already have a acoount'))
],
)),
)),
),
);
}
}
When declaring a function or variable you have follow proper declaring method to avoid unusual issues. You have declare your function using Void the V is in capital case there but it must be in small case like void. Juts change this like :
final Void Function(
to
final void Function(
import 'package:flutter/material.dart';
void main(List<String> args) {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(),
home: AuthScreen(),
);
}
}
class AuthScreen extends StatefulWidget {
#override
_AuthScreenState createState() => _AuthScreenState();
}
class _AuthScreenState extends State<AuthScreen> {
void _submitAuthForm(
String email, String password, String username, bool isLogin) {}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).primaryColor,
body: Authform(
_submitAuthForm,
));
}
}
class Authform extends StatefulWidget {
Authform(this.submitFN);
final void Function(
String email, String password, String username, bool isLogin) submitFN;
#override
_AuthformState createState() => _AuthformState();
}
class _AuthformState extends State<Authform> {
final _formKey = GlobalKey<FormState>();
var _isLogin = true;
var _userEmail;
var _userName;
var _userPassword;
void _trySubmit() {
final isValid = _formKey.currentState!.validate();
FocusScope.of(context).unfocus();
if (isValid) {
_formKey.currentState!.save();
widget.submitFN(_userEmail, _userPassword, _userName, _isLogin);
}
}
#override
Widget build(BuildContext context) {
return Center(
child: Card(
margin: EdgeInsets.all(20),
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextFormField(
key: ValueKey('email'),
validator: (value) {
if (value!.isEmpty || !value.contains('#')) {
return 'please enter valid email address';
}
return null;
},
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
icon: Icon(
Icons.mail,
color: Colors.orange,
),
labelText: 'Email Addess'),
onSaved: (value) {
_userEmail = value;
},
),
if (!_isLogin)
TextFormField(
key: ValueKey('username'),
validator: (value) {
if (value!.isEmpty || value.length < 4) {
return 'Username is short enter atleast 4 characters ';
}
},
decoration: InputDecoration(
icon: Icon(
Icons.person,
color: Colors.orange,
),
labelText: 'Username'),
onSaved: (value) {
_userName `enter code here`= value;
},
),
TextFormField(
key: ValueKey('password'),
validator: (value) {
if (value!.isEmpty || value.length < 7) {
return 'Password must be atleast 7 characters long';
}
return null;
},
decoration: InputDecoration(
icon: Icon(
Icons.lock,
color: Colors.orange,
),
labelText: 'password',
),
obscureText: true,
onSaved: (value) {
_userPassword = value;
},
),
SizedBox(
height: 12,
),
ElevatedButton(
onPressed: _trySubmit,
child: Text(_isLogin ? 'Login' : 'Signup'),
style: ElevatedButton.styleFrom(onPrimary: Colors.white),
),
TextButton(
onPressed: () {
setState(() {
_isLogin = !_isLogin;
});
},
child: Text(_isLogin
? 'Create new account'
: 'I already have a acoount'))
],
)),
)),
),
);
}
}
account_screen.dart
child: AuthForm(
submitFn: _submitAuthForm,
),

Null Safety Issue in flutter

if (_formKey.currentState.validate()) {
setState(() {
buttonChanged = false;
});
}
according to my logic, the above statement would let me sign in with a login and password validation, but i keep getting an error
The method 'validate' can't be unconditionally invoked because the receiver can be 'null'.
Try making the call conditional (using '?.') or adding a null check to the target ('!').
when i do if (_formKey.currentState!.validate()) error goes away but my validation does not work, login happens even when it shouldnt.
Kindly help me with this issue, i am a beginner, learning flutter app developement via youtube.
this is my whole code
import 'package:flutter/material.dart';
import 'routes.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);
#override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
bool buttonChanged = false;
String name = "";
final _formKey = GlobalKey<FormState>();
moveToHome(BuildContext context) async {
if (_formKey.currentState.validate()) {
setState(() {
buttonChanged = false;
});
}
await Future.delayed(const Duration(seconds: 1));
await Navigator.pushNamed(context, route.home);
setState(() {
buttonChanged = false;
});
}
#override
Widget build(BuildContext context) {
return Material(
color: Colors.grey[500],
child: Form(
key: _formKey,
child: Column(
children: [
const CircleAvatar(backgroundImage: AssetImage('images/login.jpg')),
const SizedBox(height: 15.0),
Text('Welcome $name',
style: const TextStyle(
fontSize: 24.0, fontWeight: FontWeight.bold)),
const SizedBox(height: 15.0),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 15, vertical: 32),
child: Column(
children: [
TextFormField(
decoration: const InputDecoration(
hintText: 'Enter the username',
labelText: 'UserName:'),
onChanged: (value) {
name = value;
setState(() {});
},
validator: (value) {
if (value != null && value.isEmpty) {
return 'Please enter the username';
}
return null;
}),
TextFormField(
obscureText: true,
decoration: const InputDecoration(
hintText: 'Enter the password',
labelText: 'Password:'),
validator: (value) {
if (value != null && value.isEmpty) {
return 'Please enter the password';
} else if (value != null && value.length < 6) {
return 'Password must be atleast 6 characters';
} else {
return null;
}
}),
const SizedBox(height: 15.0),
Material(
borderRadius:
BorderRadius.circular(buttonChanged ? 50.0 : 10.0),
color: Colors.blue,
child: InkWell(
splashColor: Colors.red,
onTap: () => moveToHome(context),
child: AnimatedContainer(
duration: const Duration(seconds: 1),
width: buttonChanged ? 50 : 130,
height: 50,
alignment: Alignment.center,
child: buttonChanged
? const Icon(Icons.done)
: const Text(
'Login',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 16),
),
),
))
],
))
],
),
),
);
}
}
Your validation logic must be:
If the user’s input isn’t valid, the validator function returns a String containing an error message. If there are no errors, the validator must return null.
But you're using incorrect code in your validator property. The following code:
validator: (value) {
if (value != null && value.isEmpty) {
return 'Please enter the username';
}
return null;
}),
will always return null if you haven't insert the text to TextFormField. So,
_formKey.currentState!.validate() will always return true if both of your TextFormFields are without text.
To solve the problem, change the code like the following:
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter the username';
}
return null;
}),

type 'Null' is not a subtype of type 'File' of 'image' flutter problem

I uploaded my image to FireStore. When I am creating an image it's perfectly ok everything uploading perfectly. After SignUp I can easily go to the user profile and can see the user name and email. But when I log out from the user profile and from my LOGIN from when providing existing email and password which I have created already then the Exception is thrown. I am not getting the issue. Exception has occurred.
_TypeError (type 'Null' is not a subtype of type 'File' of 'image')
import 'dart:io';
import '../picker/user_image_picker.dart';
import 'package:flutter/material.dart';
class AuthForm extends StatefulWidget {
AuthForm(this.submitFn, this.isLoading);
final bool isLoading;
var submitFn;
void function(
String email,
String password,
String userName,
File image,
bool isLogin,
BuildContext ctx,
);
#override
_AuthFormState createState() => _AuthFormState();
#override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
class _AuthFormState extends State<AuthForm> {
final _formKey = GlobalKey<FormState>();
var _isLogin = true;
var _userEmail = '';
var _userName = '';
var _userPasssword = '';
File? userImageFile;
void pickedImage(File image) {
userImageFile = image;
}
void _trySubmit() {
final isValid = _formKey.currentState!.validate();
FocusScope.of(context).unfocus();
if (userImageFile == null && !_isLogin) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Please Pick an Image.'),
backgroundColor: Theme.of(context).errorColor,
),
);
return;
}
if (isValid) {
_formKey.currentState?.save();
print(_userEmail);
print(_userName);
print(_userPasssword);
print(' Good to go ');
widget.submitFn(
_userEmail.trim(),
_userPasssword.trim(),
_userName.trim(),
userImageFile,
_isLogin,
context,
);
} else {
print('Form is not valid');
}
}
#override
Widget build(BuildContext context) {
return Card(
margin: EdgeInsets.all(20),
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
if (!_isLogin) UserImagePicker(pickedImage),//this is my image file
TextFormField(
key: ValueKey('email'),
onSaved: (value) {
_userEmail = value!;
},
validator: (value) {
if (value!.isEmpty ||
!value.contains(RegExp(
'^[a-zA-Z0-9+_.-]+#[a-zA-Z0-9.-]+.[a-z]+.[com]'))) {
return 'enter valid Email';
//print('Email validation is not ok');
} else {
return null;
}
},
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: 'Email Address', icon: Icon(Icons.email)),
),
if (!_isLogin)
TextFormField(
key: ValueKey('userName'),
onSaved: (value) {
_userName = value!;
},
validator: (value) {
if (value == null || value.length < 4) {
return 'Enter At least 4 charaters ';
}
return null;
},
decoration: InputDecoration(
labelText: 'User Name', icon: Icon(Icons.person)),
),
TextFormField(
key: ValueKey('password'),
onSaved: (value) {
_userPasssword = value!;
},
obscureText: true,
validator: (value) {
if (value == null || value.isEmpty || value.length < 7) {
return 'Enter at least 7 Digits';
}
return null;
},
decoration: InputDecoration(
labelText: 'Password',
icon: Icon(
Icons.security,
),
),
),
SizedBox(
height: 20,
),
if (widget.isLoading) CircularProgressIndicator(),
if (!widget.isLoading)
ElevatedButton(
child: Text(_isLogin ? 'Login' : 'Signup'),
onPressed: _trySubmit,
),
if (widget.isLoading) CircularProgressIndicator(),
if (!widget.isLoading)
TextButton(
style: TextButton.styleFrom(
primary: Theme.of(context).primaryColor,
),
child: Text(_isLogin
? 'Create New Account'
: 'I already have an account'),
onPressed: () {
setState(
() {
_isLogin = !_isLogin;
},
);
},
)
],
),
),
),
),
);
}
}
Looks like userImageFile is null. This happen because this variable is nullable, and when it gets passed to submitFn (which weirdly is a dynamic variable...?) it throws, because it expects a non-nullable image parameter.

How to initialise a type ValueChanged in Dart/Flutter?

I am new in Flutter, specially Flutter for Web. I am trying to reach something that's probably easy and basic, but I am facing difficulty.
This is my main.dart
Widget build(BuildContext context) {
bool loggedIn = false;
return MaterialApp(
home: loggedIn ? Navigator(
pages: [
MaterialPage(child: DashboardPage())
],
onPopPage: (route, result) => route.didPop(result),
) : LoginPage(didLoggedIn: (user) => print('Hello, ' + user) )
);
}
}
What I am trying to archive : if not logged in, go to the login screen. After the user successfully login, I'd like to execute a callback that will print hello (in fact I will set the state to logged in, but nevermind).
However I am facing difficulty to implement this callback, and maybe I am doing a wrong approach. This is the login page code:
import 'package:flutter/material.dart';
import 'package:email_validator/email_validator.dart';
class LoginPage extends StatefulWidget {
#override
LoginPageState createState() {
return LoginPageState();
}
}
class LoginPageState extends State<LoginPage> {
final username = TextEditingController();
final password = TextEditingController();
final _formKey = GlobalKey<FormState>();
bool rememberMe = true;
//final ValueChanged didLoggedIn;
Widget _buildUsernameField() {
return TextFormField(
controller: username,
decoration: InputDecoration(labelText: 'Your E-Mail'),
validator: (value) {
if (value == null ||
value.isEmpty ||
!EmailValidator.validate(value)) {
return 'Invalid E-Mail';
}
return null;
});
}
Widget _buildPasswordField() {
return TextFormField(
controller: password,
obscureText: true,
decoration: InputDecoration(labelText: 'Password'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your password';
}
return null;
});
}
#override
Widget build(BuildContext context) {
return Card(
child: Container(
color: Colors.white,
alignment: Alignment.center,
child: Container(
//color: Colors.green,
width: 600,
height: 300,
child: Column(
children: [
Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_buildUsernameField(),
_buildPasswordField(),
],
),
),
Column(
children: [
CheckboxListTile(title: Text('Remember me') ,
controlAffinity: ListTileControlAffinity.leading,
value: rememberMe, onChanged: (bool? value) {
setState(() {
rememberMe = value!;
});
}),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
print(username.text + "/" + password.text);
//didLoggedIn(username.text);
}
},
child: Text('Log me in'),
),
Text('Forgot your password ?')
],
)
],
),
),
),
);
}
}
The problem is this line : final ValueChanged didLoggedIn;
It says that I need to initialise it. How to do that ?
And by the way, as I said, I am newbie, so maybe this could not be the best way to archive my goals, so if someone wants to give me a better solution, this will be more than welcomed.
Thanks !
You need to change 'LoginPage' like below.
move 'didLoggedIn' to 'LoginPage' not 'LoginPageState'.
make a constructor of 'LoginPage' to receive 'didLoggedIn'
access 'didLoggedIn' using 'widget.' prefix.
import 'package:flutter/material.dart';
import 'package:email_validator/email_validator.dart';
class LoginPage extends StatefulWidget {
final ValueChanged didLoggedIn;
LoginPage({required this.didLoggedIn});
#override
LoginPageState createState() {
return LoginPageState();
}
}
class LoginPageState extends State<LoginPage> {
final username = TextEditingController();
final password = TextEditingController();
final _formKey = GlobalKey<FormState>();
bool rememberMe = true;
Widget _buildUsernameField() {
return TextFormField(
controller: username,
decoration: InputDecoration(labelText: 'Your E-Mail'),
validator: (value) {
if (value == null ||
value.isEmpty ||
!EmailValidator.validate(value)) {
return 'Invalid E-Mail';
}
return null;
});
}
Widget _buildPasswordField() {
return TextFormField(
controller: password,
obscureText: true,
decoration: InputDecoration(labelText: 'Password'),
validator: (value) {
if (value == null || value.isEmpty) {
return 'Please enter your password';
}
return null;
});
}
#override
Widget build(BuildContext context) {
return Card(
child: Container(
color: Colors.white,
alignment: Alignment.center,
child: Container(
//color: Colors.green,
width: 600,
height: 300,
child: Column(
children: [
Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
_buildUsernameField(),
_buildPasswordField(),
],
),
),
Column(
children: [
CheckboxListTile(title: Text('Remember me') ,
controlAffinity: ListTileControlAffinity.leading,
value: rememberMe, onChanged: (bool? value) {
setState(() {
rememberMe = value!;
});
}),
ElevatedButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
print(username.text + "/" + password.text);
//didLoggedIn(username.text);
widget.didLoggedIn(username.text);
}
},
child: Text('Log me in'),
),
Text('Forgot your password ?')
],
)
],
),
),
),
);
}
}
You need to create a constructor for LoginPage to save the callback on this class, then when you need to use the callback in LoginPageState you use the widget.callbackName() or widget.callbackName.call().

Flutter pressing back button pops up previous snackBar from Login page again

I have a LoginPage in Flutter. After login, it shows a small snackbar with "success" or "failure.." if password is wrong, then it navigates to the todo list.
When I now press the "back" button on an Android device, it navigates back to the login screen. However, there is still the snackbar popping up and saying "Login successful, redirecting..", and also, my textfields are not emptied and still have the values from the first login, why? That should not happen, but I cannot figure out why that is... here is my code:
import 'package:flutter/material.dart';
import 'package:todoey_flutter/components/rounded_button.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:todoey_flutter/util/file_handler.dart';
import 'package:provider/provider.dart';
class LoginScreen extends StatefulWidget {
#override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
String username;
String password;
String hashedPW;
// Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
var _nameController = TextEditingController();
var _pwController = TextEditingController();
#override
Widget build(BuildContext context) {
CryptOid cy = Provider.of<CryptOid>(context, listen: true);
FileHandler fh = Provider.of<FileHandler>(context, listen: true);
return Scaffold(
backgroundColor: Colors.white,
body: Builder(
builder: (BuildContext scaffoldBuildContext) {
return Container(
//inAsyncCall: isSpinning,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 34.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
/*
Flexible(
child: Hero(
tag: 'logo',
child: Container(
height: 200.0,
child: Image.asset('images/logo.png'),
),
),
),*/
SizedBox(
height: 48.0,
),
TextField(
controller: _nameController,
style: TextStyle(color: Colors.black54),
onChanged: (value) {
//Do something with the user input.
username = value.toLowerCase();
},
decoration: InputDecoration(
hintText: 'Enter your username',
),
),
SizedBox(
height: 8.0,
),
TextField(
controller: _pwController,
obscureText: true,
style: TextStyle(color: Colors.black54),
onChanged: (value) {
//Do something with the user input.
password = value;
},
decoration: InputDecoration(
hintText: 'Enter your password',
),
),
SizedBox(
height: 24.0,
),
RoundedButton(
title: 'Login',
colour: Colors.lightBlueAccent,
onPressed: () async {
Scaffold.of(scaffoldBuildContext).removeCurrentSnackBar();
print("user: $username, pw: $password");
if ((username != '' && username != null) && (password != '' && password != null)) {
SharedPreferences prefs = await SharedPreferences.getInstance();
// cy.test();
if ((username != '' && username != null) && prefs.containsKey(username)) {
hashedPW = prefs.getString(username);
bool decryptPW = await cy.deHash(hashedPW, password);
if (decryptPW) {
cy.setUsername(username);
fh.setUser(username);
prefs.setString('activeUser', username);
Scaffold.of(scaffoldBuildContext).showSnackBar(
SnackBar(
content: Text("Login successful! redirecting.."),
),
);
Navigator.pushNamed(context, 'taskScreen');
} else {
Scaffold.of(scaffoldBuildContext).showSnackBar(
SnackBar(
content: Text("Wrong password for user $username!"),
),
);
}
} else {
String hashedPW = await cy.hashPW(password);
prefs.setString('activeUser', username);
prefs.setString(username, hashedPW);
cy.setUsername(username);
fh.setUser(username);
Scaffold.of(scaffoldBuildContext).showSnackBar(
SnackBar(
content: Text("User created successful! redirecting.."),
),
);
Navigator.pushNamed(context, 'taskScreen');
//prefs.setString(username, hashedPW);
}
_nameController.clear();
_pwController.clear();
} else {
Scaffold.of(scaffoldBuildContext).showSnackBar(
SnackBar(
content: Text("User and password may not be empty.."),
),
);
_nameController.clear();
_pwController.clear();
return;
}
},
),
],
),
),
);
},
),
);
}
}
You should create a ScaffoldState GlobalKey then assign the to the scaffold.
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: Container());
}
The use the key to showSnackBar
void _showInSnackBar(String value) {
_scaffoldKey.currentState
.showSnackBar(new SnackBar(content: new Text(value)));
}
So your full code would look like this:
import 'package:flutter/material.dart';
import 'package:todoey_flutter/components/rounded_button.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:todoey_flutter/util/file_handler.dart';
import 'package:provider/provider.dart';
class LoginScreen extends StatefulWidget {
#override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
String username;
String password;
String hashedPW;
// Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
var _nameController = TextEditingController();
var _pwController = TextEditingController();
#override
Widget build(BuildContext context) {
CryptOid cy = Provider.of<CryptOid>(context, listen: true);
FileHandler fh = Provider.of<FileHandler>(context, listen: true);
return Scaffold(
key: _scaffoldKey,
backgroundColor: Colors.white,
body: Builder(
builder: (BuildContext scaffoldBuildContext) {
return Container(
//inAsyncCall: isSpinning,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 34.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
/*
Flexible(
child: Hero(
tag: 'logo',
child: Container(
height: 200.0,
child: Image.asset('images/logo.png'),
),
),
),*/
SizedBox(
height: 48.0,
),
TextField(
controller: _nameController,
style: TextStyle(color: Colors.black54),
onChanged: (value) {
//Do something with the user input.
username = value.toLowerCase();
},
decoration: InputDecoration(
hintText: 'Enter your username',
),
),
SizedBox(
height: 8.0,
),
TextField(
controller: _pwController,
obscureText: true,
style: TextStyle(color: Colors.black54),
onChanged: (value) {
//Do something with the user input.
password = value;
},
decoration: InputDecoration(
hintText: 'Enter your password',
),
),
SizedBox(
height: 24.0,
),
RoundedButton(
title: 'Login',
colour: Colors.lightBlueAccent,
onPressed: () async {
_scaffoldKey.currentState.removeCurrentSnackBar();
print("user: $username, pw: $password");
if ((username != '' && username != null) &&
(password != '' && password != null)) {
SharedPreferences prefs =
await SharedPreferences.getInstance();
// cy.test();
if ((username != '' && username != null) &&
prefs.containsKey(username)) {
hashedPW = prefs.getString(username);
bool decryptPW = await cy.deHash(hashedPW, password);
if (decryptPW) {
cy.setUsername(username);
fh.setUser(username);
prefs.setString('activeUser', username);
_showInSnackBar("Login successful! redirecting..");
Navigator.pushNamed(context, 'taskScreen');
} else {
_showInSnackBar(
"Wrong password for user $username!");
}
} else {
String hashedPW = await cy.hashPW(password);
prefs.setString('activeUser', username);
prefs.setString(username, hashedPW);
cy.setUsername(username);
fh.setUser(username);
_showInSnackBar(
"User created successful! redirecting..");
Navigator.pushNamed(context, 'taskScreen');
//prefs.setString(username, hashedPW);
}
_nameController.clear();
_pwController.clear();
} else {
_showInSnackBar("User and password may not be empty..");
_nameController.clear();
_pwController.clear();
return;
}
},
),
],
),
),
);
},
),
);
}
void _showInSnackBar(String value) {
_scaffoldKey.currentState
.showSnackBar(new SnackBar(content: new Text(value)));
}
}