DropdownButton selection calls the onValidate functions of other fields in Flutter - flutter

Not sure what I'm missing. When selecting the value of drop-down, form onVaidate() fired which hence my other fields are showing the error. How can I stop it? Here is the code
Widget build(BuildContext context) {
// return Scaffold(
// appBar: AppBar(title: Text("Registration")),
// body: Center(child: Text(widget.user.displayName)),
// );
FirebaseUser user = widget.user;
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Text("Registration"),
),
body: SafeArea(
top: false,
bottom: false,
child: Form(
key: _formKey,
autovalidate: true,
child: ListView(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
children: <Widget>[
TextFormField(
validator: (value) => value.isEmpty ? 'Name is Required' : null,
decoration: const InputDecoration(
icon: const Icon(Icons.person),
hintText: 'Enter your first and last name',
labelText: 'Name',
),
),
TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.phone),
hintText: 'Enter a phone number',
labelText: 'Phone',
),
initialValue: user.phoneNumber,
enabled: user.phoneNumber == null,
keyboardType: TextInputType.phone,
validator: (value) => value.isEmpty ? 'Phone number is Required' : null
// inputFormatters: [
// WhitelistingTextInputFormatter.digitsOnly,
// ],
),
TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.email),
hintText: 'Enter a email address',
labelText: 'Email',
),
initialValue: user.email,
enabled: user.email == null,
validator: (value) => value.isEmpty ? 'Email is Required' : null,
keyboardType: TextInputType.emailAddress,
),
TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.remove_red_eye),
hintText: 'Enter the Password',
labelText: 'Password',
),
keyboardType: TextInputType.text,
obscureText: true,
validator: (value) => value.isEmpty ? 'Password is Required' : null
),
FormField(
builder: (FormFieldState state) {
return InputDecorator(
decoration: InputDecoration(
icon: const Icon(Icons.card_membership),
labelText: 'ID Type',
),
isEmpty: _profile.govId == null,
child: DropdownButtonHideUnderline(
child: DropdownButton(
value: _profile.govId,
isDense: true,
onChanged: (String newValue) {
setState(() {
_profile.govId = newValue;
state.didChange(newValue);
});
},
items: _govtIds.map((String value) {
return DropdownMenuItem(
value: value,
child: Text(value),
);
}).toList(),
),
),
);
},
),
TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.confirmation_number),
hintText: 'Enter your Governmenr ID number',
labelText: 'ID Number',
),
keyboardType: TextInputType.datetime,
validator: (value) => value.isEmpty ? 'ID Number is Required' : null
),
FormField(
builder: (FormFieldState state) {
return InputDecorator(
decoration: InputDecoration(
icon: const Icon(Icons.business),
labelText: 'Block Info',
),
isEmpty: _profile.block == null,
child:
// Column(children: [RadioListTile(title: Text("A")),RadioListTile(title: Text("B"))]),
// Radio(
// value: 0,
// groupValue: _blocks,
// onChanged: (value){}),
DropdownButtonHideUnderline(
child:
DropdownButton(
value: _profile.block,
isDense: true,
onChanged: (String newValue) {
setState(() {
_profile.block = newValue;
state.didChange(newValue);
});
},
items: _blocks.map((String value) {
return DropdownMenuItem(
value: value,
child: Text(value),
);
}).toList(),
),
),
);
},
),
TextFormField(
decoration: const InputDecoration(
icon: const Icon(Icons.home),
hintText: 'Enter your Flat number',
labelText: 'Flat number',
),
inputFormatters: [LengthLimitingTextInputFormatter(3)],
validator: (value) {
if (value.isEmpty) {
return 'Flat number is Required';
} else if (_profile.isValidHouseNumber() == false) {
return 'Invalid flat number';
} else {
return null;
}
},
keyboardType: TextInputType.number,
onChanged:(value) {
_profile.houseNo = value;
},
),
Padding(
padding: EdgeInsets.fromLTRB(38.0, 30.0, 0.0, 0.0),
child: SizedBox(
height: 50.0,
child: FlatButton(
// elevation: 5.0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0)),
color: Colors.green,
child: Text('Submit',
style: TextStyle(fontSize: 20.0, color: Colors.white)),
onPressed: _validateAndSubmit,
),
))
],
))),
);
}

Call a method to return null in the validate fucntion all the other fields. That will clear the validation. It's a fix, but doesn't solve the problem.
There seems to be nothing wrong with the code above, can you add the code for the other fields too?
EDIT:
The reason all the other fields validate is because of the autovalidate: true property of the parent Form widget. Remove it and wrap each TextFormField with a Form with different keys.
For example, your TextFormField should look as follows:
Form(
key: _formKey[0],
child: TextFormField(
validator: (value) => value.isEmpty ? 'Name is Required' : null,
decoration: const InputDecoration(
icon: const Icon(Icons.person),
hintText: 'Enter your first and last name',
labelText: 'Name',
),
),
),
Wrap it with a Form, _formKey is declared as
List<GlobalObjectKey<FormState>> _formKey = new List(number_of_keys);
Call the respective setState like so:
_formKey[position].currentState.setState((){});
And don't forget to remove the parent Form widget.

Related

How to update variables of a State class inside of an external Widget?

I'm new in flutter, Can someone help me how to access the ss variable or the setState protected method of a State class I created inside of a Widget outside that class. I'm trying to organize codes that's why I extract the Widget out of that State class.
main.dart
import 'package:flutter/material.dart';
import 'screens.dart';
void main() => runApp(const App());
enum ScreenState {
home,
login,
register,
}
class App extends StatefulWidget {
const App({super.key});
#override
State<StatefulWidget> createState() => _AppState();
}
class _AppState extends State<App> {
ScreenState ss = ScreenState.register;
#override
Widget build(BuildContext context) {
switch (ss) {
case ScreenState.register:
return registerPage();
default:
return registerPage();
}
}
}
screens.dart
import 'package:flutter/material.dart';
import 'components.dart';
Widget registerPage() {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.blueGrey,
),
home: Scaffold(
appBar: appHeader(),
body: registerForm(),
),
);
}
components.dart
import 'package:flutter/material.dart';
PreferredSizeWidget appHeader() {
return AppBar(
title: const Text('Register Form'),
actions: [
TextButton(
child: const Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Text(
'Home',
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.underline,
),
),
),
onPressed: () {/* _AppState.ss = ScreenState.home; */},
),
TextButton(
child: const Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Text(
'Log In',
style: TextStyle(
color: Colors.white,
decoration: TextDecoration.underline,
),
),
),
onPressed: () {/* _AppState.ss = ScreenState.login; */},
),
],
);
}
Widget registerForm() {
return SingleChildScrollView(
child: Center(
child: Container(
constraints: const BoxConstraints(
minWidth: 300,
maxWidth: 500,
),
padding: const EdgeInsets.symmetric(
vertical: 40,
horizontal: 20,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Text('Account Information'),
const SizedBox(
height: 10,
),
TextFormField(
keyboardType: TextInputType.text,
decoration: const InputDecoration(
labelText: 'Create username',
hintText: 'Enter username',
prefixIcon: Icon(Icons.person),
border: OutlineInputBorder(),
),
onChanged: (String value) {},
validator: (value) {
return value!.isEmpty ? 'Please create a username' : null;
},
),
const SizedBox(
height: 10,
),
TextFormField(
keyboardType: TextInputType.visiblePassword,
decoration: const InputDecoration(
labelText: 'Create password',
hintText: 'Enter password',
prefixIcon: Icon(Icons.lock),
border: OutlineInputBorder(),
),
onChanged: (String value) {},
validator: (value) {
return value!.isEmpty ? 'Please create a password' : null;
},
),
const SizedBox(
height: 10,
),
TextFormField(
keyboardType: TextInputType.visiblePassword,
decoration: const InputDecoration(
labelText: 'Re-enter password',
hintText: 'Enter password',
prefixIcon: Icon(Icons.lock),
border: OutlineInputBorder(),
),
onChanged: (String value) {},
validator: (value) {
return value!.isEmpty ? 'Please re-enter password' : null;
},
),
const SizedBox(
height: 30,
),
const Text('Personal information'),
const SizedBox(
height: 10,
),
TextFormField(
keyboardType: TextInputType.text,
decoration: const InputDecoration(
labelText: 'Last name',
hintText: 'Enter your last name',
prefixIcon: Icon(Icons.edit),
border: OutlineInputBorder(),
),
onChanged: (String value) {},
validator: (value) {
return value!.isEmpty ? 'Please enter your last name' : null;
},
),
const SizedBox(
height: 10,
),
TextFormField(
keyboardType: TextInputType.text,
decoration: const InputDecoration(
labelText: 'First name',
hintText: 'Enter your first name',
prefixIcon: Icon(Icons.edit),
border: OutlineInputBorder(),
),
onChanged: (String value) {},
validator: (value) {
return value!.isEmpty ? 'Please enter your first name' : null;
},
),
const SizedBox(
height: 10,
),
TextFormField(
keyboardType: TextInputType.text,
decoration: const InputDecoration(
labelText: 'Middle name (optional)',
hintText: 'Enter your middle name',
prefixIcon: Icon(Icons.edit),
border: OutlineInputBorder(),
),
onChanged: (String value) {},
),
const SizedBox(
height: 10,
),
TextFormField(
keyboardType: TextInputType.text,
decoration: const InputDecoration(
labelText: 'Suffix (optional)',
hintText: 'Enter your suffix',
prefixIcon: Icon(Icons.edit),
border: OutlineInputBorder(),
),
onChanged: (String value) {},
),
],
),
),
),
);
}
I commented out the code that I expect to work but it turns out to be an error. Please teach me on how to fix the error. Thank you so much.
You can change your state to this:
class _AppState extends State<App> {
ScreenState ss = ScreenState.register;
#override
Widget build(BuildContext context) {
switch (ss) {
case ScreenState.register:
return registerPage(changeState);
default:
return registerPage(changeState);
}
}
void changeState(ScreenState s) {
setState(() {
ss = s;
});
}
}
Then registerPage like
Widget registerPage(Function(ScreenState) f) {
with
appBar: appHeader(f),
and then appHeader like
PreferredSizeWidget appHeader(Function(ScreenState) f) {
and then this for example:
onPressed: () {f(ScreenState.home);},

The flutter application not moving to the home page after registration/signing up

After the user signup, the application isn't redirecting the user to the homepage, but the application is been notified that a user just signed in.
This is the registration page, before this page the user is asked to verify his/her email address before they can access this page.
import 'package:chi_application/application/pages/authentication/login_page.dart';
import 'package:chi_application/application/pages/authentication/wrapper.dart';
import 'package:chi_application/application/services/AuthServiceController.dart';
import 'package:chi_application/application/shared/form_field_decoration.dart';
import 'package:chi_application/application/shared/snackbar.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:one_context/one_context.dart';
class CustomerRegistrationForm extends StatefulWidget {
late String em;
CustomerRegistrationForm(this.em);
#override
State<CustomerRegistrationForm> createState() =>
_CustomerRegistrationFormState();
}
class _CustomerRegistrationFormState extends State<CustomerRegistrationForm> {
String? email;
#override
void initState() {
// TODO: implement initState
super.initState();
email = widget.em;
}
final formkey = GlobalKey<FormState>();
String? password,
username,
lastname,
firstname,
confirmPassword,
phone,
selectedGender;
List<String> gender = ['Male', 'Female'];
bool? _isChecked = false;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: BackButton(
onPressed: () => Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => LoginPage()),
ModalRoute.withName("/login")),
),
iconTheme: IconThemeData(color: Colors.white),
backgroundColor: Color(0xff991F36),
elevation: 0,
title: Text(
'Customer Registration',
style: TextStyle(
//color: Colors.grey[600],
fontWeight: FontWeight.bold,
//fontFamily: 'Poppins',
fontSize: 16,
),
),
),
body: SingleChildScrollView(
child: Form(
key: formkey,
child: Container(
padding: EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Please fill in the following details',
style: TextStyle(
fontFamily: 'Poppins',
color: Color(0xff991F36),
fontWeight: FontWeight.bold,
fontSize: 15),
),
SizedBox(
height: 10,
),
TextFormField(
onChanged: (value) => this.username = value,
validator: (value) =>
value!.isEmpty ? 'User Name Field cant be empty' : null,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
decoration:
textFormDecoration().copyWith(hintText: 'Username'),
),
SizedBox(
height: 20,
),
TextFormField(
onChanged: (value) => this.lastname = value,
validator: (value) =>
value!.isEmpty ? 'Last Name Field cant be empty' : null,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
decoration:
textFormDecoration().copyWith(hintText: 'Last Name'),
),
SizedBox(
height: 20,
),
TextFormField(
onChanged: (value) => this.firstname = value,
validator: (value) =>
value!.isEmpty ? 'First name Field cant be empty' : null,
keyboardType: TextInputType.text,
textInputAction: TextInputAction.next,
decoration:
textFormDecoration().copyWith(hintText: 'First Name'),
),
SizedBox(
height: 20,
),
TextFormField(
onChanged: (value) => this.phone = value,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
],
validator: (value) => value!.isEmpty
? 'Phone Number Field cant be empty'
: null,
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
decoration:
textFormDecoration().copyWith(hintText: 'Phone Number'),
),
SizedBox(
height: 20,
),
TextFormField(
obscureText: true,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
],
autovalidateMode: AutovalidateMode.onUserInteraction,
onChanged: (value) => this.password = value,
validator: (value) {
if (value!.length < 6) {
return 'Password must be more than 6 characters';
} else if (value.isEmpty) {
return 'Password Field cant be empty';
}
},
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
decoration:
textFormDecoration().copyWith(hintText: 'Password'),
),
SizedBox(
height: 20,
),
TextFormField(
obscureText: true,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
],
autovalidateMode: AutovalidateMode.onUserInteraction,
onChanged: (value) => this.confirmPassword = value,
validator: (value) {
if (value!.length < 6) {
return 'Confirm Password must be more than 6 characters';
} else if (value.isEmpty) {
return 'Confirm Password Field cant be empty';
} else if (value != password) {
return 'Password doesnt match';
}
},
keyboardType: TextInputType.number,
textInputAction: TextInputAction.next,
decoration: textFormDecoration()
.copyWith(hintText: 'Confirm Password'),
),
SizedBox(
height: 20,
),
Container(
padding: EdgeInsets.only(left: 10, right: 10),
width: double.maxFinite,
color: Colors.grey[100],
child: DropdownButton<String>(
underline: Container(),
isExpanded: true,
hint: Text('Gender'), // Not necessary for Option 1
value: selectedGender,
onChanged: (newValue) {
setState(() {
selectedGender = newValue;
});
},
items: gender.map((gen) {
return DropdownMenuItem(
child: new Text(gen),
value: gen,
);
}).toList(),
),
),
CheckboxListTile(
checkColor: Colors.white,
activeColor: Colors.pink,
title: Text(
"Subscribe to our Newslwtters?",
style: TextStyle(fontWeight: FontWeight.bold),
),
value: _isChecked,
onChanged: (newValue) {
setState(() {
_isChecked = newValue;
});
},
controlAffinity:
ListTileControlAffinity.leading, // <-- leading Checkbox
),
SizedBox(
height: 20,
),
ButtonTheme(
buttonColor: Color(0xff991F36),
minWidth: double.infinity,
height: 50,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(5)),
child: RaisedButton(
onPressed: () async {
if (formkey.currentState!.validate()) {
try {
await AuthController().signUp(
password: password!,
gender: selectedGender!,
firstname: firstname!,
isChecked: _isChecked!,
lastname: lastname!,
context: context,
email: email!,
phone: phone!,
username: username!);
showSnackBar(context, 'Registration Successful!!!');
removeAllAndPush();
} catch (e) {
print(e.toString());
}
}
},
child: Text(
'Complete',
style: TextStyle(
color: Colors.white,
fontFamily: 'Poppins',
fontSize: 15,
fontWeight: FontWeight.bold,
),
),
),
),
],
),
),
),
),
);
}
}
removeAllAndPush() {
try {
OneContext()
.pushNamedAndRemoveUntil('/wrapper', (Route<dynamic> route) => false);
} catch (e) {
print("Error while navigating : $e");
}
}
This is my wrapper page
import 'package:chi_application/application/pages/authentication/login_page.dart';
import 'package:chi_application/application/pages/screens/home_pages.dart';
import 'package:chi_application/application/services/AuthServiceController.dart';
import 'package:chi_application/application/shared/loading.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Wrapper extends StatelessWidget {
const Wrapper({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: AuthController().authChanges(),
builder: (context, snapshot) {
final provider = Provider.of<AuthController>(context, listen: false);
if (provider.isSigningIn) {
return Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.hasData) {
return HomePage();
} else {
return LoginPage();
}
},
);
}
}
I don't know what the problem is now. It wont navigate to the homepage, only after you restart the application.

Set width size of TextFormField with prefix to match normal TextFormField

is there anyway to make TextFormField with prefix have same size with normal TextFormField? Tried to wrap it with container, but I'm afraid if using different device with different width will affect it. Thank you.
This is my code
TextFormField(
textInputAction: TextInputAction.next,
controller: namaField,
focusNode: _namaFocus,
autovalidateMode: AutovalidateMode.always,
decoration: const InputDecoration(
border: OutlineInputBorder(),
icon: Icon(Icons.person),
labelText: 'Nama Lengkap',
),
validator: (String? value) {
if (value == null || value.isEmpty) {
return 'Mohon Isikan Data';
}
return null;
},
),
SizedBox(height: 5),
TextFormField(
textInputAction: TextInputAction.done,
autovalidateMode: AutovalidateMode.always,
keyboardType: TextInputType.phone,
controller: noHpField,
focusNode: _noHpFocus,
decoration: const InputDecoration(
border: OutlineInputBorder(),
isDense: true,
prefixIcon: Padding(
padding: EdgeInsets.fromLTRB(4, 6, 4, 7),
child: Text("+62",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold)),
),
prefixIconConstraints:
BoxConstraints(minWidth: 0, minHeight: 0),
icon: Icon(Icons.phone_android),
labelText: 'No HP',
),
validator: (String? value) {
if (value == null || value.isEmpty) {
return 'Mohon Isikan Data';
}
return null;
},
),
Remove isDense: true.
Full Code :
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Welcome Flutter'),
),
body: new SafeArea(
top: true,
bottom: true,
child: Column(
children: [
SizedBox(
height: 20,
),
TextFormField(
textInputAction: TextInputAction.next,
controller: namaField,
focusNode: _namaFocus,
autovalidateMode: AutovalidateMode.always,
decoration: const InputDecoration(
border: OutlineInputBorder(),
icon: Icon(Icons.person),
labelText: 'Nama Lengkap',
),
validator: (String? value) {
if (value == null || value.isEmpty) {
return 'Mohon Isikan Data';
}
return null;
},
),
SizedBox(height: 5),
TextFormField(
textInputAction: TextInputAction.done,
autovalidateMode: AutovalidateMode.always,
keyboardType: TextInputType.phone,
controller: noHpField,
focusNode: _noHpFocus,
decoration: const InputDecoration(
border: OutlineInputBorder(),
// isDense: true, <-- Comment this.
prefixIcon: Padding(
padding: EdgeInsets.fromLTRB(4, 6, 4, 7),
child: Text("+62", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
),
prefixIconConstraints: BoxConstraints(minWidth: 0, minHeight: 0),
icon: Icon(Icons.phone_android),
labelText: 'No HP',
),
validator: (String? value) {
if (value == null || value.isEmpty) {
return 'Mohon Isikan Data';
}
return null;
},
),
],
)));
}
}
Try this:
Container(
width:MediaQuery.of(context).size.width*0.90,
child: TextFormField(
textInputAction: TextInputAction.next,
controller: namaField,
focusNode: _namaFocus,
autovalidateMode: AutovalidateMode.always,
decoration: const InputDecoration(
border: OutlineInputBorder(),
icon: Icon(Icons.person),
labelText: 'Nama Lengkap',
),
validator: (String? value) {
if (value == null || value.isEmpty) {
return 'Mohon Isikan Data';
}
return null;
},
),),

Flutter DropdownButton show label when option is selected

Can a Dropdown Button:
return DropdownButton<String>(
items: <String>['Foo', 'Bar'].map((String value) {
return new DropdownMenuItem<String>(
value: value,
child: new Text(value),
);
}).toList(),
onChanged: (_) {},
);
have something similar to a decoration user in a TextFormField:
TextFormField(
controller: _titleController,
decoration: InputDecoration(labelText: 'Input'),
validator: (String value) {
if (value != null && value.isEmpty) {
return 'Please enter some text';
}
},
style: Theme.of(context).textTheme.title,
),
When something is written in the above TextFormField the word Input shows. Like this:
Replace DropdownButton with DropdownButtonFormField:
https://api.flutter.dev/flutter/material/DropdownButtonFormField-class.html
Change DropdownButton to DropdownButtonFormField and add this decoration....
decoration: InputDecoration(
filled: true,
fillColor: Hexcolor('#ecedec'),
labelText: 'Occupation',
border: new CustomBorderTextFieldSkin().getSkin(),
),
Copy Paste and see magic
I have done flutter dropdown with material design
Padding(
padding: const EdgeInsets.all(9.0),
child: InputDecorator(
decoration: InputDecoration(
labelText: 'Priority',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0)),
contentPadding: EdgeInsets.all(10),
),
child: ButtonTheme(
materialTapTargetSize: MaterialTapTargetSize.padded,
child: DropdownButton<String>(
hint: const Text("Priority"),
isExpanded: true,
value: dropdownValue,
elevation: 16,
underline: DropdownButtonHideUnderline(
child: Container(),
),
onChanged: (String? newValue) {
setState(() {
dropdownValue = newValue!;
});
},
items: <String>['One', 'Two', 'Free', 'Four']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
),
),
),

Flutter Layout Problem. How to get all the fields the same length

I'm developing a registration screen.
I can't get all the fields with the same length in the screen.
They are different types of fields: ListTile, Dropdown button, and Checkbox. I'm new to Flutter. Can I apply any parameter to get the same padding on both sides?
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text("Register"),
),
body: new Stack(
children: [
new Padding(
padding: const EdgeInsets.only(
left: 16.0, top: 30.0, right: 16.0, bottom: 16.0),
child: ListView(
children: <Widget>[
new ListTile(
leading: const Icon(Icons.person),
title: TextField(
decoration: InputDecoration(
labelText: "Username : ", hintText: " Username ",
errorText: _correctUsername ? null : 'Complete Username',),
onSubmitted: (value) {
_checkInput();
},
controller: _usernameController,
),
),
new FormField(
builder: (FormFieldState state) {
return InputDecorator(
decoration: InputDecoration(
icon: const Icon(Icons.person),
labelText: 'Gender',
errorText: _correctGender ? null : 'Select Gender',),
child: new DropdownButtonHideUnderline(
child: new DropdownButton(
value: _selectedGender,
items: _dropDownMenuGender,
onChanged: changedDropDownGender,
),
),
);
},
),
new ListTile(
leading: const Icon(Icons.person),
title: TextField(
decoration: InputDecoration(
labelText: "About me : ", hintText: " About me "),
controller: _aboutController,
),
),
new FormField(
builder: (FormFieldState state) {
return InputDecorator(
decoration: InputDecoration(
icon: const Icon(Icons.person),
labelText: 'I have a car',
),
child: new Checkbox(
value: _havecar, onChanged: _havecarChanged));
},
),
],
),
),
]
),
);
}
Any help will be appreciated.
Regards.
Replace your ListTiles with just and note the icon property.
TextField(
decoration: InputDecoration(
labelText: "Username : ",
hintText: " Username ",
icon: const Icon(Icons.person),
errorText: _correctUsername ? null : 'Complete Username',
),
onSubmitted: (value) {
_checkInput();
},
controller: _usernameController,
),