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

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,
),

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);},

how to get save the value from textfromfield and pass it back to page?

import 'package:flutter/material.dart';
import 'package:mmitra/widgets/header.dart';
import 'home.dart';
class CreateAccount extends StatefulWidget {
#override
_CreateAccountState createState() => _CreateAccountState();
}
class _CreateAccountState extends State<CreateAccount> {
late String username;
final _key = Global Key<FormState>();
#override
Widget build(BuildContext parentContext) {
return Scaffold(
appBar: header(context, titleText: 'Create Account'),
body: ListView(children: [
Container(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.only(top: 25),
child: Center(
child: Text(
'Create a username',
style: TextStyle(fontSize: 25.0),
),
),
),
Padding(
padding: EdgeInsets.all(16.0),
child: Form(
child: TextFormField(
key: _key,
// controller: myController,
onSaved: (val) => username = val!,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelStyle: TextStyle(fontSize: 15),
labelText: 'Username',
hintText: 'Must be at least 3 Characters'),
),
),
),
GestureDetector(
onTap: () {
_key.currentState!.save();
Navigator.pop(context, username
);
},
child: Container(
height: 50,
width: 300,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(7)),
child: Center(
child: Text(
'Submit',
style:
TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
),
),
),
),
],
),
),
]),
);
}
}
and I'm getting below shown errors:
Exception caught by gesture
The following Cast Error was thrown while handling a gesture
Null check operator used on a null value
I just want to get the textfromfield value and i want to pass it to the home.dart page in order to create the document in firebase collection
you must define a EditTextControll() ex:textController and set it to TextFormField to controller paramerter , and then get text as textController.text and pass with Navigatoer .
for pass wihtin first screen to two screen
Firstly /
TextEditingController controller = TextEditingController();
Secoundly /
body: Form(
child: TextFormField(
controller: controller,
onTap: (){
//here SettingsScreen() is example
// name is paramerter in the secound screen
Navigator.push(context,
MaterialPageRoute(builder: (context)=>SettingsScreen(name:controller.text),),
);
},
),
),
You added key in TextFormField
Form(
child: TextFormField(
key: _key,
// controller: myController,
onSaved: (val) => username = val!,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelStyle: TextStyle(fontSize: 15),
labelText: 'Username',
hintText: 'Must be at least 3 Characters'),
),
),
),
Remove it from TextFormField and Add it in Form
Just Like:
Form(
key: _key,
child: TextFormField(
// controller: myController,
onSaved: (val) => username = val!,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelStyle: TextStyle(fontSize: 15),
labelText: 'Username',
hintText: 'Must be at least 3 Characters'),
),
),
),
This will Solve your Issue.

DropdownButton selection calls the onValidate functions of other fields in 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.

How to fix "Another exception was thrown: NoSuchMethodError: The getter 'value' was called on null" error

I was trying to create a register page for my app, but when i load the page i got this error
I'm working with Flutter in Visual Studio code
Widget build(BuildContext context) {
TextFormField email = new TextFormField(
validator: (value) {
Pattern pattern =
r'^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$';
RegExp regex = new RegExp(pattern);
if (!regex.hasMatch(value))
return 'Ingrese un correo valido';
else
return null;
},
controller: emailcontroller,
decoration: InputDecoration(
hintText: 'Email',
prefixIcon: Icon(Icons.account_circle),
border: _textFieldBorder,
),
style: TextStyle(),
textAlign: TextAlign.left,
);
TextFormField name = new TextFormField(
controller: namecontroller,
decoration: InputDecoration(
hintText: 'Nombre',
prefixIcon: Icon(Icons.person_pin),
border: _textFieldBorder,
),
style: TextStyle(),
textAlign: TextAlign.left,
validator: (value) {
if (value.isEmpty) {
return 'Este campo no puede estar vacio';
} else
return null;
},
);
TextFormField cellphone = new TextFormField(
maxLength: 9,
controller: phonecontroller,
decoration: InputDecoration(
hintText: 'Phone',
prefixIcon: Icon(Icons.phone),
border: _textFieldBorder,
),
style: TextStyle(),
textAlign: TextAlign.left,
);
TextFormField password = new TextFormField(
controller: passwordcontroller,
obscureText: true,
decoration: InputDecoration(
hintText: 'Contraseña',
prefixIcon: Icon(Icons.lock),
border: _textFieldBorder,
),
style: TextStyle(),
textAlign: TextAlign.left,
);
TextFormField confirmpassword = new TextFormField(
obscureText: true,
decoration: InputDecoration(
hintText: 'Repita la contraseña',
prefixIcon: Icon(Icons.lock),
border: _textFieldBorder,
),
style: TextStyle(),
textAlign: TextAlign.left,
validator: (value) {
if (value == passwordcontroller.text) {
return null;
} else {
return 'Las contraseñas no son iguales';
}
},
);
return Scaffold(
appBar: AppBar(
title: Text(
'Registro',
style: TextStyle(fontSize: 35),
),
backgroundColor: Color(0xff2196F3),
centerTitle: true,
),
body: Mutation(
options: MutationOptions(
document: query,
),
builder: (RunMutation insert, QueryResult result) {
return new SingleChildScrollView(
child: Form(
key: _formKey,
child: Center(
child: Container(
height: MediaQuery.of(context).size.height / 1.1,
child: Padding(
padding: EdgeInsets.fromLTRB(30, 0, 30, 0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
email,
SizedBox(height: 8),
name,
SizedBox(height: 8),
cellphone,
SizedBox(height: 8),
password,
SizedBox(height: 8),
confirmpassword,
Divider(height: 40),
GestureDetector(
onTap: () {
if (_formKey.currentState.validate()) {
insert(<String, dynamic>{
"name": namecontroller.text,
"phone": phonecontroller.text,
"password": passwordcontroller.text,
"email": emailcontroller.text
});
Navigator.pop(context);
}
},
child: new Container(
height: 50,
width: MediaQuery.of(context).size.width / 1.2,
decoration: BoxDecoration(
color: Color(0xff2196F3),
border: Border.all(
width: 1.0, color: Colors.transparent),
borderRadius: BorderRadius.all(
Radius.circular(10.0)
), ),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Text('Registrarse', style: _loginTextStyle)
],
),
),
)
],
),
),
),
),
),
);
}));
}
I expect to see the register page but the only thing i get is this error "Another exception was thrown: NoSuchMethodError: The getter 'value' was called on null"
The problem was that i was using a GraphQL client and that client uses an instance of my widget called RegisterPage, and i was trying to navigate to RegisterPage , but the correct thing to do was navigate to my GraphQL client called RegistarPageGraphQL and that client build the RegisterPage

Catch tap event on TextFormField

I am trying to catch the tap event on TextFormField into a flutter Form.
I use a GestureDetector to do that with the TextFormField as child but nothing is firing when a click on it :
#override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
appBar: new AppBar(title: const Text('Recherche de sorties')),
body: new DropdownButtonHideUnderline(
child: new Form(
key: _formKey,
autovalidate: _autovalidate,
child: new ListView(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
children: <Widget>[
new DatePicker(
labelText: 'Date',
selectedDate: widget.request.dateDebut,
initialDate: widget.request.dateDebut,
firstDate: new DateTime.now().add(new Duration(days: -1)),
lastDate: new DateTime.now().add(new Duration(days: 365 * 4)),
selectDate: (DateTime value) {
setState(() {
widget.request.dateDebut = value;
});
},
datePickerMode: DatePickerMode.day,
icon: const Icon(Icons.date_range),
),
new InputDecorator(
decoration: const InputDecoration(
labelText: 'Rayon',
hintText: '-- Choisissez un rayon --',
icon: const Icon(Icons.settings_backup_restore),
),
isEmpty: widget.request.rayon == null,
child: new DropdownButton<String>(
value: widget.request.rayon.toString(),
isDense: true,
onChanged: (String newValue) {
setState(() {
widget.request.rayon = int.parse(newValue);
});
},
items: _rayons.keys.map((int key) {
return new DropdownMenuItem<String>(
value: key.toString(),
child: new Text(_rayons[key]),
);
}).toList(),
),
),
new GestureDetector(
onTap: () async {
print("Container clicked");
Prediction p = await showGooglePlacesAutocomplete(
context: context,
apiKey: Consts.googlePlacesApiKey,
mode: Mode.fullscreen,
language: "fr",
components: [new Component(Component.country, "fr")]);
if (p != null) {
(_scaffoldKey.currentState).showSnackBar(
new SnackBar(content: new Text(p.description)));
}
},
child: new TextFormField(
// controller: controller,
decoration: const InputDecoration(
icon: const Icon(Icons.room),
hintText: 'Où êtes vous ?',
labelText: 'Localisation',
),
),
),
new Container(
padding: const EdgeInsets.all(20.0),
alignment: Alignment.center,
child: new Align(
alignment: const Alignment(0.0, -0.2),
child: new ButtonBar(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
new RaisedButton(
child: const Text('ANNULER'),
onPressed: _fermerCritereRecherche,
),
new RaisedButton(
child: const Text('VALIDER'),
onPressed: _valider,
),
],
),
)),
]),
),
),
);
}
If i replace :
new GestureDetector(
onTap: () async {
print("Container clicked");
Prediction p = await showGooglePlacesAutocomplete(
context: context,
apiKey: Consts.googlePlacesApiKey,
mode: Mode.fullscreen,
language: "fr",
components: [new Component(Component.country, "fr")]);
if (p != null) {
(_scaffoldKey.currentState).showSnackBar(
new SnackBar(content: new Text(p.description)));
}
},
child: new TextFormField(
// controller: controller,
decoration: const InputDecoration(
icon: const Icon(Icons.room),
hintText: 'Où êtes vous ?',
labelText: 'Localisation',
),
),
),
By a simple Container it is working :
new GestureDetector(
onTap: () async {
print("Container clicked");
Prediction p = await showGooglePlacesAutocomplete(
context: context,
apiKey: Consts.googlePlacesApiKey,
mode: Mode.fullscreen,
language: "fr",
components: [new Component(Component.country, "fr")]);
if (p != null) {
(_scaffoldKey.currentState).showSnackBar(
new SnackBar(content: new Text(p.description)));
}
},
child: new Container(
width: 80.0,
height: 80.0,
margin: new EdgeInsets.all(10.0),
color: Colors.black),
),
Do you have any ideas how to make GestureDetector work with TextFormField ? Maybe with a controller but i have tried without any success
Thanks in advance
Simply use onTap Method of TextFormField:
TextFormField(
onTap: () {
print("I'm here!!!");
}
)
Wrap TextFormField widget With AbsorbPointer widget , then OnTap() works definitely
here is an example:-
GestureDetector(
onTap: () => dialog(),
child: AbsorbPointer(
child: TextFormField(
textInputAction: TextInputAction.newline,
decoration: new InputDecoration(
fillColor: Colors.grey,
border: OutlineInputBorder(
borderRadius:
BorderRadius.all(Radius.circular(6.0)),
borderSide:
BorderSide(color: Colors.grey[100]),
gapPadding: 4),
labelText: "Enter your mood",
labelStyle: TextStyle(
letterSpacing: 1,
color: Colors.grey,
fontSize: 13),
hintMaxLines: 1),
validator: (val) {
if (val == "") return "Field can't be empty";
},
keyboardType: TextInputType.text,
enabled: true,
textAlign: TextAlign.justify,
minLines: 3,
autofocus: false,
style: new TextStyle(
fontSize: 16.0,
color: Colors.black,
),
maxLines: 10,
),
),
),
Wrap AbsorbPointer Widget with Gesture Detector, and then work in onTap(). it will work fine.
I have found a solution by using the InputDecorator (from the flutter gallery) :
child: new InputDecorator(
decoration: const InputDecoration(
labelText: 'Localisation',
icon: const Icon(Icons.room),
),
child: widget.request.localisationLibelle != null
? new Text(widget.request.localisationLibelle)
: new Text("-- Choisissez un lieu --"),
),
Instead of using a TextFormField that catch the tap at the place of the GestureDetector I use a simple child Text of the InputDecorator widget.
I just solved this myself using Flutter 0.6.0.
The GestureDetector object takes in a behavior property from this enum to determine how to defer actions.
Small snippet of the GestureDetector taking priority over a TextFormField:
new GestureDetector(
onTap: onTap,
behavior: HitTestBehavior.opaque,
child: new TextFormField(
enabled: onTap == null,
*other stuff here*
),
)
The onTap object is a Function object I declare outside of this. I also set the enabled property based on my onTap object, so I can ensure that if I want to capture a tap, the text form field is disabled.
onTap function is working but if you use it with InputDecoration { enabled: false }, it will not working.
decoration: InputDecoration(
enabled: false, // not working when on tap
isDense: true,
filled: true,
fillColor: _listRadioItemPosition.isEmpty ? Colors.grey[100] : Colors.white,
border: UnderlineInputBorder(borderSide: BorderSide(color: Color(0xFFC4C4C4), width: 1)),
),
onTap: (){
displayBottomSheetPosition(context);
},