I'm trying to create an UI for a signup page with a little overlap between the container that contains the TextFormFields and the blue container that is only for decoration. But, when I do so, using a Stack widget and a Positioned to set the position of the white Container, my TextFormFields don't work (they don't open the keyboard when I click). The FlatButton I used also isn't working. I wonder what I'm doing wrong...
enter image description here
class TelaCadastro extends StatefulWidget {
#override
_TelaCadastroState createState() => _TelaCadastroState();
}
final GlobalKey<FormState> _cadastroKey = GlobalKey<FormState>();
final FirebaseAuth _auth = FirebaseAuth.instance;
final TextEditingController _nomeController = TextEditingController();
final TextEditingController _emailController = TextEditingController();
final TextEditingController _senhaController = TextEditingController();
final TextEditingController _confirmarSenhaController = TextEditingController();
class _TelaCadastroState extends State<TelaCadastro> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0,
title: Text('Cadastrar'),
),
body: Stack(
overflow: Overflow.visible,
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 17),
color: Colors.indigo,
height: 150,
child: Align(
alignment: Alignment.centerLeft,
child: Container(
width: MediaQuery.of(context).size.width - 50,
child: Text('A Corretora trabalha com as melhores '
'seguradoras do mercado',
style: TextStyle(fontSize: 21, color: Colors.white),),
),
),
),
SizedBox(height: 15,),
Positioned(
width: MediaQuery.of(context).size.width - 30,
left: 15,
top: 135,
child: Container(
height: 460,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
),
child: Form(
key: _cadastroKey,
child: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.person_add, color: Colors.indigo,),
Text(' Cadastre-se abaixo!',
style: TextStyle(fontSize: 16, color: Colors.indigo),),
],
),
SizedBox(height: 15),
TextFormField(
controller: _nomeController,
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(10))
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(10))
) ,
prefixIcon: Icon(Icons.person),
hintText: 'Nome Completo',
filled: true,
fillColor: Colors.grey[200]
),
),
SizedBox(height: 20,),
TextFormField(
controller: _emailController,
validator: (String texto){
if (texto.isEmpty || !texto.contains('#')){
return 'Por favor, informe um email válido';
}
return null;
},
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(10))
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(10))
) ,
prefixIcon: Icon(Icons.email),
hintText: 'Email',
filled: true,
fillColor: Colors.grey[200]
),
),
SizedBox(height: 20,),
TextFormField(
controller: _senhaController,
validator: (String texto){
if (texto.isEmpty || texto.length < 6){
return 'Por favor, informe uma senha válida';
}
return null;
},
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(10))
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(10))
) ,
prefixIcon: Icon(Icons.lock),
hintText: 'Senha',
filled: true,
fillColor: Colors.grey[200]
),
obscureText: true,
),
SizedBox(height: 20,),
TextFormField(
controller: _confirmarSenhaController,
validator: (String texto){
if (texto.isEmpty || texto.length < 6){
return 'Por favor, informe uma senha válida';
}
return null;
},
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(10))
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.transparent),
borderRadius: BorderRadius.all(Radius.circular(10))
) ,
prefixIcon: Icon(Icons.lock),
hintText: 'Confirme sua Senha',
filled: true,
fillColor: Colors.grey[200]
),
obscureText: true,
),
SizedBox(height: 30,),
Builder(
builder: (context) => Container(
width: MediaQuery.of(context).size.width - 30,
height: 50,
decoration: BoxDecoration(
color: Colors.indigo,
borderRadius: BorderRadius.all(Radius.circular(10))
),
child: FlatButton(
child: Text('Criar Conta', style: TextStyle(color: Colors.white),),
onPressed: (){
print('test');
},
),
),
),
SizedBox(height: 15,)
],
),
),
),
),
),
],
)
);
}
}
Here I had Commented your SizedBox widget and wrapped blue Container which is only for decoration with Positioned widget also giving appropriate width and height.
Now its completely working/!!
You can copy and paste run the full code below:-
class TelaCadastro extends StatefulWidget {
#override
_TelaCadastroState createState() => _TelaCadastroState();
}
final GlobalKey<FormState> _cadastroKey = GlobalKey<FormState>();
//final FirebaseAuth _auth = FirebaseAuth.instance;
final TextEditingController _nomeController = TextEditingController();
final TextEditingController _emailController = TextEditingController();
final TextEditingController _senhaController = TextEditingController();
final TextEditingController _confirmarSenhaController = TextEditingController();
class _TelaCadastroState extends State<TelaCadastro> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0,
title: Text('Cadastrar'),
),
body: Stack(
overflow: Overflow.visible,
children: <Widget>[
Positioned(
width: 414,
height: 150,
child: Container(
padding: EdgeInsets.only(left: 17),
color: Colors.indigo,
height: 150,
child: Align(
alignment: Alignment.centerLeft,
child: Container(
width: MediaQuery.of(context).size.width - 50,
child: Text(
'A Corretora trabalha com as melhores '
'seguradoras do mercado',
style: TextStyle(fontSize: 21, color: Colors.white),
),
),
),
),
),
// SizedBox(
// height: 15,
// ),
Positioned(
width: MediaQuery.of(context).size.width - 30,
left: 15,
top: 135,
child: Container(
height: 460,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
),
child: Form(
key: _cadastroKey,
child: Padding(
padding: EdgeInsets.only(left: 15, right: 15),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.person_add,
color: Colors.indigo,
),
Text(
' Cadastre-se abaixo!',
style:
TextStyle(fontSize: 16, color: Colors.indigo),
),
],
),
SizedBox(height: 15),
TextFormField(
controller: _nomeController,
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.transparent),
borderRadius:
BorderRadius.all(Radius.circular(10))),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.transparent),
borderRadius:
BorderRadius.all(Radius.circular(10))),
prefixIcon: Icon(Icons.person),
hintText: 'Nome Completo',
filled: true,
fillColor: Colors.grey[200]),
),
SizedBox(
height: 20,
),
TextFormField(
controller: _emailController,
validator: (String texto) {
if (texto.isEmpty || !texto.contains('#')) {
return 'Por favor, informe um email válido';
}
return null;
},
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.transparent),
borderRadius:
BorderRadius.all(Radius.circular(10))),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.transparent),
borderRadius:
BorderRadius.all(Radius.circular(10))),
prefixIcon: Icon(Icons.email),
hintText: 'Email',
filled: true,
fillColor: Colors.grey[200]),
),
SizedBox(
height: 20,
),
TextFormField(
controller: _senhaController,
validator: (String texto) {
if (texto.isEmpty || texto.length < 6) {
return 'Por favor, informe uma senha válida';
}
return null;
},
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.transparent),
borderRadius:
BorderRadius.all(Radius.circular(10))),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.transparent),
borderRadius:
BorderRadius.all(Radius.circular(10))),
prefixIcon: Icon(Icons.lock),
hintText: 'Senha',
filled: true,
fillColor: Colors.grey[200]),
obscureText: true,
),
SizedBox(
height: 20,
),
TextFormField(
controller: _confirmarSenhaController,
validator: (String texto) {
if (texto.isEmpty || texto.length < 6) {
return 'Por favor, informe uma senha válida';
}
return null;
},
decoration: InputDecoration(
enabledBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.transparent),
borderRadius:
BorderRadius.all(Radius.circular(10))),
focusedBorder: OutlineInputBorder(
borderSide:
BorderSide(color: Colors.transparent),
borderRadius:
BorderRadius.all(Radius.circular(10))),
prefixIcon: Icon(Icons.lock),
hintText: 'Confirme sua Senha',
filled: true,
fillColor: Colors.grey[200]),
obscureText: true,
),
SizedBox(
height: 30,
),
Builder(
builder: (context) => Container(
width: MediaQuery.of(context).size.width - 30,
height: 50,
decoration: BoxDecoration(
color: Colors.indigo,
borderRadius:
BorderRadius.all(Radius.circular(10))),
child: FlatButton(
child: Text(
'Criar Conta',
style: TextStyle(color: Colors.white),
),
onPressed: () {
print('test');
},
),
),
),
SizedBox(
height: 15,
)
],
),
),
),
),
),
],
));
}
}
Related
I am creating a class to edit some user fields:
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: true,
appBar: AppBar(
backgroundColor: AppColors.rojoMovMap,
title: Text("miperfil".tr()),
),
body: SingleChildScrollView(
child:Column(
children: [
Row(
children: [
Text(
"tuemail".tr(),
style: TextStyle(
color: AppColors.grisMovMap,
fontWeight: FontWeight.bold,
fontSize: 18),
),
],
),
Row(
children: [
Text(
widget.usuario.email,
style: TextStyle(color: AppColors.grisMovMap, fontSize: 16),
)
],
),
SizedBox(
height: 10,
),
SizedBox(height: 5,),
TextField(
controller: controladorUsername,
keyboardType: TextInputType.text,
maxLength: 18,
autocorrect: false,
decoration: new InputDecoration(
icon: GestureDetector(
onTap: (){
//verificar que no existe ya el username
//asignar nuevo username
},
child: new Icon(Icons.edit,color: AppColors.rojoMovMap,)),
labelText: "tuusername".tr(),
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
borderSide: const BorderSide(
color: Colors.grey,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Colors.blue),
),
),
),
SizedBox(
height: 15,
),
TextField(
controller: controladorUbicacion,
keyboardType: TextInputType.text,
autocorrect: false,
decoration: new InputDecoration(
icon: GestureDetector(
onTap: (){
//asignar nueva ciudad,provincia
},
child: new Icon(Icons.edit,color: AppColors.rojoMovMap,)),
labelText: "tuubicacion".tr(),
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
borderSide: const BorderSide(
color: Colors.grey,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Colors.blue),
),
),
),
SizedBox(
height: 15,
),
TextField(
controller: controladorPais,
keyboardType: TextInputType.text,
autocorrect: false,
decoration: new InputDecoration(
icon: GestureDetector(
onTap: (){
//asignar nuevo pais
},
child: new Icon(Icons.edit,color: AppColors.rojoMovMap,)),
labelText: "tupais".tr(),
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
borderSide: const BorderSide(
color: Colors.grey,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Colors.blue),
),
),
),
SizedBox(
height: 15,
),
TextField(
controller: controladorNombre,
keyboardType: TextInputType.text,
autocorrect: false,
decoration: new InputDecoration(
icon: GestureDetector(
onTap: (){
//asignar nuevo nombre
},
child: new Icon(Icons.edit,color: AppColors.rojoMovMap,)),
labelText: "tunombre".tr(),
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
borderSide: const BorderSide(
color: Colors.grey,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Colors.blue),
),
),
),
SizedBox(
height: 15,
),
TextField(
controller: controladorApellidos,
keyboardType: TextInputType.text,
autocorrect: false,
decoration: new InputDecoration(
icon: GestureDetector(
onTap: (){
//asignar nuevo apellidos
},
child: new Icon(Icons.edit,color: AppColors.rojoMovMap,)),
labelText: "tusapellidos".tr(),
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
borderSide: const BorderSide(
color: Colors.grey,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Colors.blue),
),
),
),
SizedBox(
height: 15,
),
TextField(
controller: controladorApellidos,
keyboardType: TextInputType.text,
autocorrect: false,
decoration: new InputDecoration(
icon: GestureDetector(
onTap: (){
//asignar nuevo apellidos
},
child: new Icon(Icons.edit,color: AppColors.rojoMovMap,)),
labelText: "tusapellidos".tr(),
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
borderSide: const BorderSide(
color: Colors.grey,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Colors.blue),
),
),
),
SizedBox(
height: 15,
),
TextField(
controller: controladorApellidos,
keyboardType: TextInputType.text,
autocorrect: false,
decoration: new InputDecoration(
icon: GestureDetector(
onTap: (){
//asignar nuevo apellidos
},
child: new Icon(Icons.edit,color: AppColors.rojoMovMap,)),
labelText: "tusapellidos".tr(),
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(20.0)),
borderSide: const BorderSide(
color: Colors.grey,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(10.0)),
borderSide: BorderSide(color: Colors.blue),
),
),
),
],
),
),
);
}
The issue is that the keyboard is overlapping some textfields:
As you may see in the code,I have wrapped the column that contains the textfields with a SingleChildScrollView and I have included resizeToAvoidBottomPadding: true, inside the scaffold.
What am Im I missing?
test this example
return Scaffold(
body: SingleChildScrollView(
physics: NeverScrollableScrollPhysics(),
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: MediaQuery.of(context).size.width,
minHeight: MediaQuery.of(context).size.height,
),
child: IntrinsicHeight(
child: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
//your code here
],
),
),
),
),
);
I am have this app that uses a checkbox to receive inputs from users, for example select a type of storage you want (NVMe, ssd, hdd etc) i want a solution that if a checkbox or multiple checkboxes are selected, it outputs their values on the summary screen.I have tried youtube tutorials, i did not quite understand them. Here is my code thanks
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:signoff_app/Screens/preview.dart';
import 'package:signoff_app/storage/store.dart';
import 'package:signoff_app/widget/textformfields.dart';
class NewSign extends StatefulWidget {
NewSign({Key? key}) : super(key: key);
#override
State<NewSign> createState() => _NewSignState();
}
class _NewSignState extends State<NewSign> {
bool ssd = false;
bool hdd = false;
bool nvme = false;
bool m2 = false;
TextEditingController pcname = new TextEditingController();
TextEditingController motherboard = new TextEditingController();
TextEditingController casing = new TextEditingController();
TextEditingController ramSize = new TextEditingController();
TextEditingController ram = new TextEditingController();
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.red,
title: Text(
'Sign Off a Computer',
style: GoogleFonts.lato(
fontSize: 16,
fontStyle: FontStyle.normal,
),
),
),
body: Container(
width: MediaQuery.of(context).size.width,
// color: Colors.black54,
child: Stack(
children: [
Container(
//margin: EdgeInsets.fromLTRB(24, 0, 0, 24),
padding: EdgeInsets.fromLTRB(32, 64, 32, 32),
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
// color: Colors.black54,
child: Column(
children: [
Expanded(
flex: 1,
child: SizedBox(
width: 100,
height: 100,
child: Image(
fit: BoxFit.contain,
image: AssetImage("./images/udlogo.png"),
),
),
),
Expanded(
flex: 3,
child: Column(
children: [
Row(
children: [
Expanded(
flex: 2,
child: TextFormField(
controller: pcname,
validator: (val) {
if (val!.isEmpty) {
return "required";
}
},
decoration: InputDecoration(
labelText: 'Pc Name',
// errorText: 'please enter pc name'
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6),
borderSide: BorderSide(
color: Colors.blue,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.grey,
width: 1.5,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.red,
width: 1.5,
),
),
),
),
),
SizedBox(
width: 24,
),
Expanded(
flex: 2,
child: TextFormField(
controller: motherboard,
decoration: InputDecoration(
labelText: 'MotherBoard',
// errorText: 'please enter pc name'
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6),
borderSide: BorderSide(
color: Colors.blue,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.grey,
width: 1.5,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.red,
width: 1.5,
),
),
),
),
),
],
),
SizedBox(
height: 62,
),
Row(
children: [
Expanded(
flex: 2,
child: TextFormField(
controller: ram,
validator: (val) {
if (val!.isEmpty) {
return "required";
}
},
decoration: InputDecoration(
labelText: 'Ram',
// errorText: 'please enter pc name'
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6),
borderSide: BorderSide(
color: Colors.blue,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.grey,
width: 1.5,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.red,
width: 1.5,
),
),
),
),
),
SizedBox(
width: 24,
),
Expanded(
flex: 2,
child: TextFormField(
controller: casing,
decoration: InputDecoration(
labelText: 'Casing',
// errorText: 'please enter pc name'
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6),
borderSide: BorderSide(
color: Colors.blue,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.grey,
width: 1.5,
),
),
errorBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(6.0),
borderSide: BorderSide(
color: Colors.red,
width: 1.5,
),
),
),
),
),
],
),
SizedBox(height: 24),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
'Storage',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w900,
),
),
SizedBox(height: 8),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
//ssd checkbox
Text("SSD"),
SizedBox(width: 2),
Checkbox(
value: ssd,
onChanged: (bool? value) {
setState(() {
ssd = value!;
});
},
),
//hdd checkbox
SizedBox(width: 16),
Text("HDD"),
SizedBox(width: 2),
Checkbox(
value: hdd,
onChanged: (bool? value) {
setState(() {
hdd = value!;
});
},
),
SizedBox(width: 16),
//Nvme checkbox
Text("NVMe"),
SizedBox(width: 2),
Checkbox(
value: nvme,
onChanged: (bool? value) {
setState(() {
ssd = value!;
});
},
),
//m.2 checkbox
SizedBox(width: 16),
Text("M.2"),
SizedBox(width: 2),
Checkbox(
value: m2,
onChanged: (bool? value) {
setState(() {
m2 = value!;
});
},
),
],
),
],
),
],
),
),
Expanded(
flex: 1,
child: Align(
alignment: Alignment.bottomCenter,
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: 45,
child: ElevatedButton(
style:
ElevatedButton.styleFrom(primary: Colors.red),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => PreviewSel(pcname.text,
motherboard.text, ram.text, casing.text),
),
);
},
child: Text('Submit'),
),
),
),
),
],
),
),
],
),
),
),
);
}
}
It seems to me that you have everything to now create your Text component. You update the booleans using setState in such a way that tapping the checkbox will update the state value, allowing you to use these variables inside a Widget, which will update when one of the values changes.
final String _summary = 'ssd: $ssd, hdd: $hdd, nvme: $nvme m2: $m2';
print(_summary); // 'ssd: false, hdd: false, nvme: false, m2: false';
...
Text(_summary);
I am creating a Password Manager Application and when user entering his details then I wont to show them a slider which generates a password in upper Password field. I have created a some code but i am not getting result as expected when user click on GENERATE PASSWORD the it show the following output.
Expected output:-
Here is my code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
class PasswordInput extends StatefulWidget {
#override
_PasswordInputState createState() => _PasswordInputState();
}
class _PasswordInputState extends State<PasswordInput> {
bool _obscureText = true;
int generatePasswordHelper = 0;
String _passwordStrength = "Hello";
int _currentRangeValues = 6;
void _toggle() {
setState(() {
_obscureText = !_obscureText;
});
}
Widget WebsiteName() {
return TextFormField(
textCapitalization: TextCapitalization.words,
keyboardType: TextInputType.text,
decoration: InputDecoration(
labelText: "Name of website",
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,
),
),
),
);
}
Widget WebsiteAddress() {
return TextFormField(
keyboardType: TextInputType.url,
decoration: InputDecoration(
labelText: "Website address",
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,
),
),
),
);
}
Widget UserName() {
return TextFormField(
keyboardType: TextInputType.emailAddress,
decoration: InputDecoration(
labelText: "Username / Email",
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,
),
),
),
);
}
Widget Password() {
return TextFormField(
keyboardType: TextInputType.text,
obscureText: _obscureText,
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,
color: Colors.grey.shade600,
),
onPressed: _toggle,
),
),
);
}
Widget Note() {
return TextFormField(
keyboardType: TextInputType.text,
textCapitalization: TextCapitalization.sentences,
maxLines: null,
decoration: InputDecoration(
labelText: "Note",
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,
),
),
),
);
}
Widget GeneratePassword() {
this.generatePasswordHelper = 0;
return Container(
padding: EdgeInsets.only(left: 10),
child: RichText(
text: TextSpan(
style: TextStyle(
color: Colors.deepOrange,
),
children: <TextSpan>[
TextSpan(
text: "GENERATE PASSWORD",
recognizer: TapGestureRecognizer()
..onTap = () {
setState(() {
generatePasswordHelper = 1;
});
})
]),
),
);
}
Widget PasswordGenerator() {
return Container(
color: Colors.grey.shade200,
//height: MediaQuery.of(context).size.width / 2,
width: MediaQuery.of(context).size.width / 1.1,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: EdgeInsets.only(left: 10),
child: Text(
_passwordStrength,
),
),
IconButton(
icon: Icon(Icons.close),
onPressed: () {
setState(() {
generatePasswordHelper = 0;
});
},
),
],
),
Slider(
value: _currentRangeValues.toDouble(),
min: 0,
max: 100,
divisions: 27,
onChanged: (double newValue) {
setState(() {
_currentRangeValues = newValue.round();
});
},
semanticFormatterCallback: (double newValue) {
return '${newValue.round()} dollars';
}
)
],
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
//resizeToAvoidBottomPadding: false,
appBar: AppBar(
centerTitle: true,
title: Text("Add Password"),
),
body: SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(),
child: Container(
padding: EdgeInsets.only(left: 16, right: 16),
child: Column(
//mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
height: 20,
),
WebsiteName(),
SizedBox(
height: 20,
),
WebsiteAddress(),
SizedBox(
height: 20,
),
UserName(),
SizedBox(
height: 20,
),
Password(),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (generatePasswordHelper == 0)
GeneratePassword()
else
PasswordGenerator()
],
),
SizedBox(
height: 20,
),
Note(),
SizedBox(
height: 20,
),
Container(
height: 50,
width: double.infinity,
child: FlatButton(
onPressed: () {},
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(
"Submit",
style: TextStyle(
color: Colors.white, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6),
),
),
),
],
),
),
),
),
);
}
}
You should provide an initalValue to your password field. Init a variable with a default blank value, then when you generate a password save it in that variable and use it as the password field value
https://api.flutter.dev/flutter/widgets/FormField/initialValue.html
class _PasswordInputState extends State<PasswordInput> {
bool _obscureText = true;
int generatePasswordHelper = 0;
String _passwordStrength = "Hello";
int _currentRangeValues = 6;
String currentPassword = ""
...
Widget Password() {
return TextFormField(
keyboardType: TextInputType.text,
obscureText: _obscureText,
initialValue: currentPassword
...
When you generate a password save it in currentPassword using setState
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.
I have 2 inputs in my bottom sheet but the problem is when I am opening keyboard it's covering the whole bottom sheet and the background page is move to the upside, not the bottom sheet.
Here is my code
class _addQuestionState extends State<addQuestion> {
void _submitData(){
Navigator.of(context).pop();
}
#override
Widget build(BuildContext context) {
double stackHeight = (MediaQuery.of(context).size.height);
return Container(
color: new Color.fromRGBO(255, 0, 0, 0.5),
child: Container(
height: stackHeight * 0.4,
decoration: BoxDecoration(
color: Color(0xff404040),
borderRadius: BorderRadius.only(topLeft: Radius.circular(15.0), topRight: Radius.circular(15.0))
),
child: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 10, left: 10, right:10,
bottom: MediaQuery.of(context).viewInsets.bottom + 10 ,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
TextField(
maxLength: 56,
style: TextStyle(
color: Colors.white,
),
textAlign: TextAlign.center,
decoration: InputDecoration(
counterText: '',
labelText: 'Would Question',
labelStyle: TextStyle(
color: Colors.blue
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue),
),
),
onSubmitted: (_) => _submitData(),
),
TextField(
maxLength: 56,
style: TextStyle(
color: Colors.white,
),
textAlign: TextAlign.center,
decoration: InputDecoration(
counterText: '',
labelText: 'Rather Question',
labelStyle: TextStyle(
color: Colors.red
),
enabledBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.red),
),
),
onSubmitted: (_) => _submitData(),
),
SizedBox(height: stackHeight * 0.04,),
RaisedButton(onPressed: () {
_submitData();
}, child: Text('Add Question', style: TextStyle(
color: Colors.white
),),color: Theme.of(context).primaryColor,
),
],
),
),
],
),
),
),
),
);
}
}
And I am calling this like
void _startAddnewTransaction(BuildContext ctx){
showModalBottomSheet(context: ctx, builder: (_) {
return addQuestion();
});
}
Here is the image
As you can see in image 2 when keyboard open the background is moving on the upside but the bottom sheet isn't moving
use SingleChildScrollView in the root for widget tree in "build" method
like this :
#override
Widget build(BuildContext context) {
double stackHeight = (MediaQuery.of(context).size.height);
return SingleChildScrollView(
child: Container(child:....));
}