how to do this kind of UI in flutter - flutter

Container( child: Column(children: [
TextFormField(
style: TextStyle(color: Colors.white.withOpacity(0.5)),
decoration: InputDecoration(
hintText: "Company",
hintStyle: TextStyle(color: Color(0xff676767)),
filled: true,
fillColor: Color(0xff1e1e1e),
border: OutlineInputBorder(
// borderRadius: BorderRadius.circular(18),
),
),
),
TextFormField(
style: TextStyle(color: Colors.white.withOpacity(0.5)),
decoration: InputDecoration(
hintText: "Title",
hintStyle: TextStyle(color: Color(0xff676767)),
filled: true,
fillColor: Color(0xff1e1e1e),
border: OutlineInputBorder(
// borderRadius: BorderRadius.circular(18),
),
),
),
]),
),
enter image description here
here is my code and a sample image of the problem. couldn't figure out how to do this

You can wrap the container with a cliprrect and adda border radius to it
ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Container(
child: Column(
children: [
TextField(),
TextField()
]
)
)
),

Use TextFormField's onFieldSubmitted() & onTap() to dynamically change border using FocusNode for Company & Title TextFormField
Initialize FocusNode for both TextField's before build().
Make sure your parent widget is a stateful widget
Color borderColor = Colors.transparent;
return Scaffold(
appBar: AppBar(),
// backgroundColor: Colo,
body: Column(
children: [
Container(
color: Colors.black,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
decoration: BoxDecoration(
color: Colors.grey[800],
borderRadius: BorderRadius.circular(20),
border: Border.all(
color: companyFN.hasFocus || titleFN.hasFocus
? Colors.blue
: Colors.transparent)
// border: Border.all(color: borderColor)
),
child: Column(children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
focusNode: companyFN,
onTap: () {
setState(() {
borderColor = Colors.blue;
});
},
onFieldSubmitted: (_) {
setState(() {
borderColor = Colors.transparent;
});
},
decoration: const InputDecoration.collapsed(
hintText: "Company",
hintStyle: TextStyle(color: Colors.grey),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
focusNode: titleFN,
decoration: const InputDecoration.collapsed(
hintText: "Title",
hintStyle: TextStyle(color: Colors.grey),
),
onTap: () {
setState(() {
borderColor = Colors.blue;
});
},
onFieldSubmitted: (_) {
setState(() {
borderColor = Colors.transparent;
});
},
),
),
])),
),
),
],
));
}
OUTPUT:

Related

Background orange text removal from button in Dart

Need to change orange color behind button to white. Dont
know where it comes from the code. Brown text is fine but behind orange one needs it to be removed. Maybe some container is taking a style. Tried removing elevated
button.style from shadow color but still not going. Please help with this. Thanks.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:matab/services/authentication_service.dart';
import 'package:matab/ui/general_widgets/generate_error_snackbar.dart';
import 'package:matab/ui/pages/onBoarding/login_page.dart';
import 'package:simple_gradient_text/simple_gradient_text.dart';
import '../styles.dart';
class SignupTextFields extends StatefulWidget {
const SignupTextFields({Key? key}) : super(key: key);
#override
State<SignupTextFields> createState() => _SignupTextFieldsState();
}
class _SignupTextFieldsState extends State<SignupTextFields> {
TextEditingController nameController = TextEditingController();
TextEditingController phoneController = TextEditingController();
TextEditingController userCnicController = TextEditingController();
TextEditingController passwordController = TextEditingController();
TextEditingController emailController = TextEditingController();
TextEditingController confirmPasswordController = TextEditingController();
bool _passwordVisible = false;
#override
Widget build(BuildContext context) {
Authentication authentication = Authentication();
return Padding(
padding: const EdgeInsets.all(10),
child: ListView(
children: <Widget>[
Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(10),
child: Text(
'SignUP'.tr,
style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 30),
)),
Container(
padding: const EdgeInsets.all(10),
child: TextField(
controller: nameController,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: 'Name'.tr,
),
),
),
Container(
padding: const EdgeInsets.all(10),
child: TextField(
controller: phoneController,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp('[0-9]'),
),
],
maxLength: 11,
keyboardType: TextInputType.number,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: 'Phone'.tr,
),
),
),
Container(
padding: const EdgeInsets.all(10),
child: TextField(
controller: emailController,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: 'Email'.tr,
),
),
),
Container(
padding: const EdgeInsets.all(10),
child: TextField(
controller: userCnicController,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp('[0-9]'),
),
],
maxLength: 13,
keyboardType: TextInputType.number,
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: 'UserCNIC'.tr,
),
),
),
Container(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
child: TextFormField(
keyboardType: TextInputType.text,
controller: passwordController,
obscureText:
!_passwordVisible, //This will obscure text dynamically
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: 'Password'.tr,
suffixIcon: IconButton(
icon: ImageIcon(
const AssetImage("assets/visibilty.png"),
color: greyColor,
),
onPressed: () {
// Update the state i.e. toogle the state of passwordVisible variable
setState(() {
_passwordVisible = !_passwordVisible;
});
},
),
),
),
),
Container(
padding: const EdgeInsets.fromLTRB(10, 10, 10, 0),
child: TextFormField(
keyboardType: TextInputType.text,
controller: confirmPasswordController,
obscureText:
!_passwordVisible, //This will obscure text dynamically
decoration: InputDecoration(
border: const OutlineInputBorder(),
labelText: 'Confirm Password'.tr,
suffixIcon: IconButton(
icon: ImageIcon(
const AssetImage("assets/visibilty.png"),
color: greyColor,
),
onPressed: () {
// Update the state i.e. toogle the state of passwordVisible variable
setState(() {
_passwordVisible = !_passwordVisible;
});
},
),
),
),
),
Padding(
padding: const EdgeInsets.fromLTRB(20.0, 10, 20, 0),
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(colors: gradientColors),
borderRadius:
const BorderRadius.all(Radius.circular(7.0))),
height: 50,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.transparent,
shadowColor: Colors.transparent,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(82.0)),
),
),
child: Text('Register'.tr),
onPressed: () {
if (nameController.text.isNotEmpty) {
if (phoneController.text.isNotEmpty) {
if (userCnicController.text.trim().length != 13) {
generateError(
"Error".tr, "CNICMustBe13DigitsLong".tr);
} else {
if (emailController.text.isNotEmpty) {
authentication.signUp(
nameController.text,
phoneController.text,
int.tryParse(
userCnicController.text.trim()) ??
0, //cnic never replaced with 0 we have already checked for null
emailController.text,
passwordController.text,
confirmPasswordController.text);
} else {
generateError(
"EmailEmpty".tr, "YouMustProvideEmail".tr);
}
}
} else {
generateError(
"PhoneCannotEmpty".tr, "EnterPhoneTryAgain".tr);
}
} else {
generateError(
"NameCannotBeEmpty".tr, "EnterNameAndTryAgain".tr);
}
},
)),
),
Row(
children: <Widget>[
Text(
'Already have an Account?'.tr,
style: TextStyle(fontSize: 20.0, color: greyColor),
),
TextButton(
child: GradientText(
'Login'.tr,
style: const TextStyle(
fontSize: 20.0,
),
gradientType: GradientType.radial,
radius: 2.5,
colors: gradientColors,
),
onPressed: () {
Get.off(const LoginPage());
},
),
],
mainAxisAlignment: MainAxisAlignment.center,
),
],
));
}
}
For the top container, it is having Radius.circular(7.0) But for Elevated button it is Radius.circular(82.0).
You need to provide same radius on both.
Padding(
padding: const EdgeInsets.fromLTRB(20.0, 10, 20, 0),
child: Container(
decoration: BoxDecoration(
gradient:
LinearGradient(colors: [Colors.red, Colors.black54]),
borderRadius: BorderRadius.all(Radius.circular(82.0)),
),
height: 50,
child: ElevatedButton(
style: ElevatedButton.styleFrom(
primary: Colors.transparent,
shadowColor: Colors.transparent,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(82.0)),
),
),
child: Text('Register'),
onPressed: () {},
)),
),
don't use shadowColor: Colors.transparent, instead use
shadowColor: Colors.white,
because the default color of your app is orange so if you do Colors.transparent it'll call default color in some cases. Also you have to remove the parent Contanier from the ElevatedButton because it is taking the background surface and changing it to orange color

Flutter - Cursor keep blinking after change Form input

I have a regular form on my APP, and when i load de screen no input is focused and no input has the cursor blinking...
Although, when run throw the inputs and fill them, or not, the cursor keeps blinking as i show on the image above:
The picture only show 3, but all of them are blinking. My point is that i need to keep only the focused input with the cursor blinking.
Heres the Form Code:
class RegisterView extends StatefulWidget {
const RegisterView({Key? key}) : super(key: key);
#override
State<RegisterView> createState() => _RegisterViewState();
}
class _RegisterViewState extends State<RegisterView> {
final _formKey = GlobalKey<FormState>();
final FocusScopeNode _node = FocusScopeNode();
String name = '';
String email = '';
String nif = '';
String password = '';
String _errorMessage = '';
TextEditingController nameCtrl = TextEditingController();
TextEditingController emailCtrl = TextEditingController();
TextEditingController nifCtrl = TextEditingController();
TextEditingController passwordCtrl = TextEditingController();
#override
void dispose() {
// TODO: implement dispose
_node.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
UserProvider userProvider =
Provider.of<UserProvider>(context, listen: false);
return Scaffold(
appBar: AppBar(
leading: const CustomBackButton(),
title: const Text('Register',
style: TextStyle(
color: kPrimaryColor,
fontSize: 16.0,
fontWeight: FontWeight.bold)),
centerTitle: true,
),
body: GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(FocusNode());
},
child: SingleChildScrollView(
child: Form(
key: _formKey,
child: FocusScope(
node: _node,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: Column(
children: [
const Padding(
padding: EdgeInsets.symmetric(vertical: 15.0),
child: Text(
'Please set your personal data:',
style:
TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
),
Padding(
padding: const EdgeInsets.only(bottom: 10.0),
child: Row(
children: [
Text(_errorMessage,
style: const TextStyle(color: Colors.red)),
],
),
),
TextFormField(
controller: nameCtrl,
keyboardType: TextInputType.number,
decoration: InputDecoration(
filled: true,
fillColor: Colors.grey[250],
contentPadding: const EdgeInsets.all(10.0),
hintText: 'Name',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: const BorderSide(
color: kPrimaryColor,
width: 2,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: const BorderSide(
color: kPrimaryColor,
width: 2,
),
),
),
onChanged: (String data) {
setState(() {
name = data;
});
},
onEditingComplete: _node.nextFocus,
),
const SizedBox(height: 15),
TextFormField(
controller: emailCtrl,
keyboardType: TextInputType.number,
decoration: InputDecoration(
filled: true,
fillColor: Colors.grey[250],
contentPadding: const EdgeInsets.all(10.0),
hintText: 'Email',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: const BorderSide(
color: kPrimaryColor,
width: 2,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: const BorderSide(
color: kPrimaryColor,
width: 2,
),
),
),
onChanged: (String data) {
setState(() {
email = data;
});
},
validator: (String? value) {
if (value!.isEmpty) {
return 'Required';
} else if (!emailRegex.hasMatch(value)) {
return 'Please set a valid email';
}
},
onEditingComplete: _node.nextFocus,
),
const SizedBox(height: 15),
TextFormField(
controller: nifCtrl,
keyboardType: TextInputType.number,
decoration: InputDecoration(
filled: true,
fillColor: Colors.grey[250],
contentPadding: const EdgeInsets.all(10.0),
hintText: 'NIF',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: const BorderSide(
color: kPrimaryColor,
width: 2,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: const BorderSide(
color: kPrimaryColor,
width: 2,
),
),
),
onChanged: (String data) {
setState(() {
nif = data;
});
},
onEditingComplete: _node.nextFocus,
),
const SizedBox(height: 15),
TextFormField(
controller: passwordCtrl,
keyboardType: TextInputType.number,
decoration: InputDecoration(
filled: true,
fillColor: Colors.grey[250],
contentPadding: const EdgeInsets.all(10.0),
hintText: 'Password',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: const BorderSide(
color: kPrimaryColor,
width: 2,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(15),
borderSide: const BorderSide(
color: kPrimaryColor,
width: 2,
),
),
),
onChanged: (String data) {
setState(() {
password = data;
});
},
validator: (String? value) {
if (value!.isEmpty) {
return 'Campo obrigatório';
} else if (value.length < 6) {
return 'Password deve conter pelo menos 6 caracteres';
}
},
onEditingComplete: _node.nextFocus,
),
const SizedBox(height: 15),
RoundedButton(
bgColor: kPrimaryColor,
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
userProvider.isLoading
? const SpinKitFadingCircle(
color: Colors.white,
size: 25.0,
)
: const Text(
'Save',
style: TextStyle(
fontSize: 16,
color: Colors.white,
fontWeight: FontWeight.w700,
),
),
],
),
onPressed: () {
if (_formKey.currentState!.validate()) {
print('Ok to register');
}
},
)
],
),
),
),
),
),
),
);
}
}

How to put a space between the AppBar and TextFormField inside a card in flutter?

#override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.teal,
),
),
Center(
child: Card(
color: Colors.tealAccent[700],
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Container(
height: 600,
width: 350,
padding: EdgeInsets.all(16),
child: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
//email
AppBar(
toolbarHeight: 30,
elevation: 00.0,
title: Text(
'Owner Registration ',
style: TextStyle(
fontSize: 25.0, fontWeight: FontWeight.bold),
),
centerTitle: true,
backgroundColor: Colors.transparent,
),
TextFormField(
maxLines: 1,
minLines: 1,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(5),
labelText: "Enter Email",
fillColor: Colors.white,
filled: true,
border: new OutlineInputBorder(
borderRadius: new BorderRadius.circular(10.0),
borderSide: new BorderSide(),
),
),
keyboardType: TextInputType.emailAddress,
validator: (value) {
if (value.isEmpty || !value.contains('#')) {
return 'invalid email';
}
return null;
},
),
//password
TextFormField(
decoration: InputDecoration(labelText: 'Password'),
obscureText: true,
controller: _passwordController,
validator: (value) {
if (value.isEmpty || value.length <= 5) {
return 'invalid password';
}
return null;
},
),
//Confirm Password
TextFormField(
decoration:
InputDecoration(labelText: 'Confirm Password'),
obscureText: true,
validator: (value) {
if (value.isEmpty ||
value != _passwordController.text) {
return 'invalid password';
}
return null;
},
onSaved: (value) {},
),
SizedBox(
height: 30,
),
RaisedButton(
child: Text('Submit'),
onPressed: () {},
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
color: Colors.white,
textColor: Colors.teal,
)
],
),
),
),
),
),
),
],
),
);
}
}
https://i.stack.imgur.com/aj4zr.png
Put a SizedBox in between AppBar and TextFormField in Column.
Put a SizedBox (with no color or same color of background) in between AppBar and TextFormField in Column, As #Lee3 said.
or put :
mainAxisAlignment: MainAxisAlignment.spaceBetween, in your Column
you can put Padding(padding: EdgeInsets.symmetric(vertical: 10)), between the AppBar and TextFromField or as #Lee3 and #Rami Ahmed said, SizedBox with some height in there.

How to visible/hide password in flutter?

I have created a login screen for my app but in password field I want a functionality like when I type password its been in * format and in right side a icon on when user click on it, password will be visible, I created a code for it but when I click on password field that icon getting invisible and when password field loose focus that icon appearing again, then how to always show that icon even password field is in focus?
I have provided a snapshot to easily understand the problem.
Here are my login screen code....
import 'package:flutter/material.dart';
import 'package:email_validator/email_validator.dart';
import 'package:secret_keeper/screens/home_screen/Home.dart';
import 'package:secret_keeper/screens/home_screen/passwords/PasswordsNavigation.dart';
import 'package:secret_keeper/screens/signup_page/SignupPage.dart';
class LoginPage extends StatefulWidget{
#override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
String _emailID, _password = "",_email = "abc#gmail.com", _pass = "Try.t.r.y#1";
bool _obscureText = true;
final _formKey = GlobalKey<FormState>();
void _toggle(){
setState(() {
_obscureText = !_obscureText;
});
}
void validateLogin(){
if(_formKey.currentState.validate()){
_formKey.currentState.save();
if(_emailID == _email && _password == _pass){
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => Home()));
}
}
}
Widget emailInput(){
return TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: "Email ID",
labelStyle: TextStyle(fontSize: 14,color: Colors.grey.shade400),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.grey.shade300,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.red,
)
),
),
validator: (email) {
if (email.isEmpty)
return 'Please Enter email ID';
else if (!EmailValidator.validate(email))
return 'Enter valid email address';
else
return null;
},
onSaved: (email)=> _emailID = email,
textInputAction: TextInputAction.next,
);
}
Widget passInput(){
return TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: "Password",
labelStyle: TextStyle(fontSize: 14,color: Colors.grey.shade400),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.grey.shade300,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.red,
)
),
suffixIcon: IconButton(
icon: Icon(
_obscureText ? Icons.visibility : Icons.visibility_off,
),
onPressed: _toggle,
),
),
validator: (password){
Pattern pattern =
r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!##\$&*~]).{8,}$';
RegExp regex = new RegExp(pattern);
if (password.isEmpty){
return 'Please Enter Password';
}else if (!regex.hasMatch(password))
return 'Enter valid password';
else
return null;
},
onSaved: (password)=> _password = password,
textInputAction: TextInputAction.done,
obscureText: _obscureText,
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
backgroundColor: Colors.white,
body: SafeArea(
child: Container(
padding: EdgeInsets.only(left: 16,right: 16),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(height: 50,),
Text("Welcome,",style: TextStyle(fontSize: 26,fontWeight: FontWeight.bold),),
SizedBox(height: 6,),
Text("Sign in to continue!",style: TextStyle(fontSize: 20,color: Colors.grey.shade400),),
],
),
Column(
children: <Widget>[
emailInput(),
SizedBox(height: 16,),
passInput(),
SizedBox(height: 12,),
Align(
alignment: Alignment.topRight,
child: Text("Forgot Password ?",style: TextStyle(fontSize: 14,fontWeight: FontWeight.w600),),
),
SizedBox(height: 30,),
Container(
height: 50,
width: double.infinity,
child: FlatButton(
onPressed: validateLogin,
padding: EdgeInsets.all(0),
child: Ink(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color(0xffff5f6d),
Color(0xffff5f6d),
Color(0xffffc371),
],
),
),
child: Container(
alignment: Alignment.center,
constraints: BoxConstraints(maxWidth: double.infinity,minHeight: 50),
child: Text("Login",style: TextStyle(color: Colors.white,fontWeight: FontWeight.bold),textAlign: TextAlign.center,),
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
),
),
SizedBox(height: 16,),
Container(
height: 50,
width: double.infinity,
child: FlatButton(
onPressed: (){},
color: Colors.indigo.shade50,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset("assets/images/facebook.png",height: 18,width: 18,),
SizedBox(width: 10,),
Text("Connect with Facebook",style: TextStyle(color: Colors.indigo,fontWeight: FontWeight.bold),),
],
),
),
),
SizedBox(height: 16,),
Container(
height: 50,
width: double.infinity,
child: FlatButton(
onPressed: (){},
color: Colors.indigo.shade50,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.asset("assets/images/facebook.png",height: 18,width: 18,),
SizedBox(width: 10,),
Text("Connect with Facebook",style: TextStyle(color: Colors.indigo,fontWeight: FontWeight.bold),),
],
),
),
),
],
),
Padding(
padding: EdgeInsets.only(bottom: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("Don't have an account?",style: TextStyle(fontWeight: FontWeight.bold),),
SizedBox(width: 5,),
GestureDetector(
onTap: (){
Navigator.push(context, MaterialPageRoute(builder: (context){
return SignupPage();
}));
},
child: Text("Sign up",style: TextStyle(fontWeight: FontWeight.bold,color: Colors.red),),
)
],
),
)
],
),
),
),
),
);
}
}
Full Example.main login here is:
take a boolean param for detecting if text is obscure or not
change suffix icon based on that boolean value
change the boolean value on suffix item click
below i gave a full example for the task.
bool _passwordInVisible = true; //a boolean value
TextFormField buildPasswordFormField() {
return TextFormField(
obscureText: _passwordInVisible,
onSaved: (newValue) => registerRequestModel.password = newValue,
onChanged: (value) {
if (value.isNotEmpty) {
removeError(error: kPassNullError);
} else if (value.length >= 8) {
removeError(error: kShortPassError);
}
return null;
},
validator: (value) {
if (value.isEmpty) {
addError(error: kPassNullError);
return "";
} else if (value.length < 8) {
addError(error: kShortPassError);
return "";
}
return null;
},
textInputAction: TextInputAction.next,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: "Password",
hintText: "Enter your password",
contentPadding: new EdgeInsets.symmetric(vertical: 5.0, horizontal: 15.0),
floatingLabelBehavior: FloatingLabelBehavior.always,
suffixIcon: IconButton(
icon: Icon(
_passwordInVisible ? Icons.visibility_off : Icons.visibility, //change icon based on boolean value
color: Theme.of(context).primaryColorDark,
),
onPressed: () {
setState(() {
_passwordInVisible = !_passwordInVisible; //change boolean value
});
},
),
),
);
}
Here two scenarios come
If you want your suffix icon color constant like always grey, you can give color property of icon, like :
button for password show hide
var passShowButton = GestureDetector(
onLongPressEnd: outContact,
onTapDown: inContact, //call this method when incontact
onTapUp:
outContact, //call this method when contact with screen is removed
child: Icon(
getXHelper.isEmailPasswordUpdate.isTrue
? AppIcons.hidePassword
: AppIcons.hidePassword,
size: 18,
color:Colors.grey
),
);
TextField
TextField(
obscureText: getXHelper.isPassInvisible ,
autocorrect: false,
textAlignVertical: TextAlignVertical.bottom,
decoration: InputDecoration(
enabled: true,
errorBorder: UnderlineInputBorder(
borderSide: BorderSide(color: AppColors.primary)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: AppColors.primary)),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: AppColors.primary)),
border: UnderlineInputBorder(
borderSide: BorderSide(color: AppColors.primary)),
fillColor: Colors.white,
filled: true,
isDense: true,
prefixIconConstraints: BoxConstraints(maxHeight: 18, minHeight: 18),
hintText: "Password",
prefixIcon: Padding(
padding: const EdgeInsets.only(top: 0, right: 12, bottom: 0),
child: Icon(Icons.lock, size: 18, color: Colors.grey),
),
suffixIcon: passShowButton,
),
cursorColor: Colors.black,
style: TextStyle(
color: Colors.black, fontFamily: AppFontFamily.fontFamily),
)
If you want your suffix icon color of your app-Primary Color, will change color when textfield focus, like :
Password show hide button
var passShowButton = GestureDetector(
onLongPressEnd: outContact,
onTapDown: inContact, //call this method when incontact
onTapUp:
outContact, //call this method when contact with screen is removed
child: Icon(
getXHelper.isEmailPasswordUpdate.isTrue
? AppIcons.hidePassword
: AppIcons.hidePassword,
size: 18,
),
);
TextField(
obscureText: getXHelper.isPassInvisible ,
autocorrect: false,
textAlignVertical: TextAlignVertical.bottom,
decoration: InputDecoration(
enabled: true,
errorBorder: UnderlineInputBorder(
borderSide: BorderSide(color: AppColors.primary)),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: AppColors.primary)),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: AppColors.primary)),
border: UnderlineInputBorder(
borderSide: BorderSide(color: AppColors.primary)),
fillColor: Colors.white,
filled: true,
isDense: true,
prefixIconConstraints: BoxConstraints(maxHeight: 18, minHeight: 18),
hintText: "Password",
prefixIcon: Padding(
padding: const EdgeInsets.only(top: 0, right: 12, bottom: 0),
child: Icon(Icons.lock, size: 18),
),
suffixIcon: passShowButton,
),
cursorColor: Colors.black,
style: TextStyle(
color: Colors.black, fontFamily: AppFontFamily.fontFamily),
)
you can put text field and icon button in a stack
replace this code with your password textfield.
you can change icon button position to what you want.
Stack(
children: [
TextFormField(
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: "Password",
labelStyle:
TextStyle(fontSize: 14, color: Colors.grey.shade400),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.grey.shade300,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: BorderSide(
color: Colors.red,
)),
),
validator: (password) {
Pattern pattern =
r'^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[!##\$&*~]).{8,}$';
RegExp regex = new RegExp(pattern);
if (password.isEmpty) {
return 'Please Enter Password';
} else if (!regex.hasMatch(password))
return 'Enter valid password';
else
return null;
},
onSaved: (password) => _password = password,
textInputAction: TextInputAction.done,
obscureText: _obscureText,
),
Positioned(
top: 2,
right: 10,
child: IconButton(
icon: Icon(
_obscureText ? Icons.visibility : Icons.visibility_off,
),
onPressed: () {
setState(() {
_obscureText = !_obscureText;
});
}),
),
],
),
I just copied and run your code and it works just fine. The icon was visible when the password field had focus. You should maybe check your flutter version or it might probably be your emulator device.
flutter --version
Flutter 1.22.3 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 8874f21e79 (2 weeks ago) • 2020-10-29 14:14:35 -0700
Engine • revision a1440ca392
Tools • Dart 2.10.3
Actually, the suffix icon is visible but when i click on TextFormField then the icon color is changing to white so simply in icon field i added a color property and give a black color to icon so even textfield is in focus its color remain black.

How to add following decoration to TextFormField in flutter?

Following is my code where I am trying to add form TextFormField with decoration as seen in mock:
Rounded border
Background colour to grey
First email and then password with text not visible
Where password field will have show button to make password visible
finally a rounded submit button
MOCK:
CODE:
class MyCustomFormState extends State<MyCustomForm> {
final _formKey = GlobalKey<FormState>();
#override
Widget build(BuildContext context) {
// Build a Form widget using the _formKey created above.
return Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
TextFormField(
decoration: InputDecoration(
fillColor: Colors.grey,
focusColor: Colors.grey
),
validator: (value) {
if (value.isEmpty) {
return 'Your email';
}
return null;
},
),
TextFormField(
decoration: InputDecoration(
fillColor: Colors.grey,
focusColor: Colors.grey
),
validator: (value) {
if (value.isEmpty) {
return 'Your password';
}
return null;
},
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 16.0),
child: RaisedButton(
onPressed: () {
// Validate returns true if the form is valid, or false
// otherwise.
if (_formKey.currentState.validate()) {
// If the form is valid, display a Snackbar.
Scaffold.of(context)
.showSnackBar(SnackBar(content: Text('Processing Data')));
}
},
child: Text('Submit'),
),
),
],
),
);
}
}
EDIT:
How to change color of this label ?
You can use borderRadius in OutlineInputBorder to make it roundable.
#override
Widget build(BuildContext context) {
// Build a Form widget using the _formKey created above.
return Scaffold(
appBar: AppBar(
title: Text('Testing'),
),
body: Form(
child: Column(
key: _formKey,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.all(10),
child: Container(
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: new BorderRadius.circular(10.0),
),
child: Padding(
padding: EdgeInsets.only(left: 15, right: 15, top: 5),
child: TextFormField(
decoration: InputDecoration(
border: InputBorder.none,
labelText: 'Email',
))))),
Padding(
padding: EdgeInsets.all(10),
child: Stack(
alignment: const Alignment(0, 0),
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: new BorderRadius.circular(10.0),
),
child: Padding(
padding:
EdgeInsets.only(left: 15, right: 15, top: 5),
child: TextFormField(
obscureText: true,
decoration: InputDecoration(
border: InputBorder.none,
labelText: 'Your password',
)))),
Positioned(
right: 15,
child: RaisedButton(
onPressed: () {
// _controller.clear();
},
child: Text('SHOW')))
],
),
),
Padding(
padding: const EdgeInsets.all(10),
child: Container(
height: 50,
width: double.infinity,
child: RaisedButton(
color: Colors.green,
onPressed: () {
// Validate returns true if the form is valid, or false
// otherwise.
if (_formKey.currentState.validate()) {
// If the form is valid, display a Snackbar.
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Processing Data')));
}
},
child: Text(
'Submit',
style: TextStyle(color: Colors.white),
),
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(18.0),
side: BorderSide(color: Colors.green)),
),
)),
],
),
));
}
Output
Edit
You can change the border color when it is clicked
#override
Widget build(BuildContext context) {
// Build a Form widget using the _formKey created above.
return Scaffold(
appBar: AppBar(
title: Text('Testing'),
),
body: Form(
child: Column(
key: _formKey,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.all(10),
child: TextField(
autofocus: false,
style: TextStyle(fontSize: 15.0, color: Colors.black),
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'Username',
filled: true,
fillColor: Colors.grey,
contentPadding: const EdgeInsets.only(
left: 14.0, bottom: 6.0, top: 8.0),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
borderRadius: BorderRadius.circular(10.0),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.grey),
borderRadius: BorderRadius.circular(10.0),
),
),
),
),
Padding(
padding: EdgeInsets.all(10),
child: Stack(
alignment: const Alignment(0, 0),
children: <Widget>[
TextField(
obscureText: true,
autofocus: false,
style: TextStyle(fontSize: 15.0, color: Colors.black),
decoration: InputDecoration(
border: InputBorder.none,
hintText: 'password',
filled: true,
fillColor: Colors.grey,
contentPadding: const EdgeInsets.only(
left: 14.0, bottom: 6.0, top: 8.0),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.red),
borderRadius: BorderRadius.circular(10.0),
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.grey),
borderRadius: BorderRadius.circular(10.0),
),
),
),
Positioned(
right: 15,
child: Container(
width: 65,
height: 30,
child: RaisedButton(
onPressed: () {
// _controller.clear();
},
child: Text(
'SHOW',
style: TextStyle(fontSize: 8),
))))
],
),
),
Padding(
padding: const EdgeInsets.all(10),
child: Container(
height: 50,
width: double.infinity,
child: RaisedButton(
color: Colors.green,
onPressed: () {
// Validate returns true if the form is valid, or false
// otherwise.
if (_formKey.currentState.validate()) {
// If the form is valid, display a Snackbar.
Scaffold.of(context).showSnackBar(
SnackBar(content: Text('Processing Data')));
}
},
child: Text(
'Submit',
style: TextStyle(color: Colors.white),
),
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(18.0),
side: BorderSide(color: Colors.green)),
),
)),
],
),
));
}
Output
Container(
padding:EdgeInsets.only(top:20,right:10,left:10),
child:Card(
shape:RoundedRectangleBorder(
borderRadius:BorderRadius.circular(20),
),
color:Colors.grey,
child: Container(
padding:EdgeInsets.only(left:12),
child: TextFormField(
decoration:InputDecoration(
hintText:"You phone number here...",
border:InputBorder.none,
fillColor:Colors.white,
),
),
),
),
),