Cannot set focus to the TextField inside ExpansionTile programmaticaly - flutter

I have an ExpansionTile with a TextField inside and trying to set the focus to this text field when user expands the tile. But for some reasons I can't get it working.
Here is the code:
ExpansionTile(
key: PageStorageKey<String>("notes_key"),
title: Text(
"Notes",
style: TextStyle(color: Colors.indigo),
),
onExpansionChanged: (expanded){
if(expanded){
FocusScope.of(context).requestFocus(_notesFocusNode);
_notesController.value = _notesController.value.copyWith(text: _notes);
} else {
_notesFocusNode.unfocus();
}
},
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: TextField(
decoration: InputDecoration(
border: InputBorder.none,
),
textInputAction: TextInputAction.newline,
style: TextStyle(color: Colors.black),
keyboardType: TextInputType.multiline,
focusNode: _notesFocusNode,
controller: _notesController,
key: PageStorageKey("notes_field_key"),
minLines: 1,
maxLines: null,
onChanged: (value) => _notes = value,
),
),
IconButton(
icon: Icon(Icons.done),
color: Colors.teal,
onPressed: () => _notesFocusNode.unfocus(),
),
],
),
],
)
Any help appreciated.
For a bigger context, the text field is not inside any form. The provided piece of code lays inside the bigger one, where it is wrapped in the ListView. Probably I need to have some parent focus scope in my view?

The TextFormField is not yet available to get Focus when you expand the Tile. It only becomes available after a few milliseconds of the animation starting. Since you don't have a way to know when the animation has finished, you can make a workaround by adding a delay. I would advise a minimum of 200 milliseconds so that the animation doesn't stagger but the TextFormField gets focus:
Future.delayed(Duration(milliseconds: 200), (){
FocusScope.of(context).requestFocus(_notesFocusNode);
});

Related

Tab key doesn't switch fields correctly (Flutter Web)

I have a question.
I have an application with various forms with textfields.
In each form i noted that when i use tab button to switch fields, focus disappear from the fields and goes i dont know where.
I tried to use Focus widget to see if on tab the focus change, and it doesn't (only when the focus return to the first field, Focus return me that it is changed)
Someone could help me? Thanks you
This is a snippet of Login form
Focus(
onFocusChange: ((value) => print("focus is changed")),
child: Column(
children: [
Semantics(
value: "Email",
child: TextFormField(
key: Key("Email"),
validator: (value) => emailValidator(value),
controller: _emailController,
),
),
const SizedBox(height: 20),
Semantics(
value: "Password",
child: TextFormField(
key: Key("Password"),
validator: (value) =>
formRequiredValidation("password", value),
textInputAction: TextInputAction.done,
obscureText: _isTypePassword,
controller: _passwordController,
onChanged: (value) {
setState(() {});
},
onFieldSubmitted: (String value) => _onSubmit(),
),
),
const SizedBox(height: 20),
SizedBox(
width: double.infinity,
height: 45,
child: ElevatedButton(
key: Key("Accedi"),
onPressed: _onSubmit,
child: const Text(
"ACCEDI",
),
),
),
const SizedBox(height: 20),
GestureDetector(
onTap: () {},
child: Text(
"Hai dimenticato la password?",
style: TextStyle(
color: Theme.of(context).primaryColor),
),
),
const SizedBox(height: 20),
GestureDetector(
onTap: () {},
child: Text(
"Non sei ancora registrato?",
style: TextStyle(
color: Theme.of(context).primaryColor),
),
),
],
),
),
Good morning,
we solved the problem by deleting the web folder and having it recreate in flutter.
We noticed that the new generated index.html file contains a third of the code compared to the old one.
It should be noted that the project started with Flutter 2 and was subsequently upgraded to Flutter 3.
Also note that with Flutter 3 important improvements have been released for the web part, including the ability to set up a loading page before starting the app or before loading it, along with other things.
Since it wasn't there in Flutter 2, we created a loading page ourselves.
it is our opinion that these changes resulted in the focus on objects not working.
Thanks to all for the precious collaboration.

Can I put the checkbox and textformfield in line with flutter?

I'm new to flutter, and right now I'm trying to do something similar to this:
img 1.
Where the textformfield is aligned inline with the checkbox, and the checkbox is shrunk at the corner, but the max that I can do is this:
img 2.
Where the checkbox is filling half of the screen, I've tried to expand the textformfield in several ways, like sizedbox, flex and expand, but none of then made the checkbox shrink to the corner and the textformfield expand, the line is always split in the middle.
The actual row code looks like this:
Row(
children: [
Expanded(
child: TextFormField(
style: TextStyle(
fontSize: 20
),
decoration: InputDecoration(
hintText: "Senha",
),
autocorrect: false,
obscureText: true,
),
),
Flexible(
child: SizedBox(
width: 10,
child: Checkbox(value: true, onChanged: (value){}),
)
)
],
),
Is there any way for me to do this?
Do I have to use a container or something like that?
Any help would be appreciated.
You can use CheckboxListTile class.
CheckboxListTile(
title: const Text('Title'),
value: value,
onChanged: (value) {
print(value);
},
);
let me know if it work for you.
I've managed to do it using flex property, as the following code shows:
Row(
children: [
Expanded(
flex: 11,
child: TextFormField(
style: TextStyle(
fontSize: 20
),
decoration: InputDecoration(
hintText: "Usuario",
),
autocorrect: false,
obscureText: true,
),
),
Flexible(
child: SizedBox(
width: 10,
child: CheckboxListTile(
value: true,
onChanged: (value) {
},
),
)
)
],
),

How can I keep the IconButton inside a TextField from focusing the text field when the button is pressed?

Here is my code for the text field inside my scaffold:
child: TextField(
obscureText: _obscureText,
controller: myController2,
focusNode: myFocusNode2,
textInputAction: TextInputAction.done,
onSubmitted: (value){
myFocusNode2.unfocus();
_loginMethod();
},
decoration: InputDecoration(
labelText: "Password",
border: OutlineInputBorder(),
suffixIcon: IconButton(
icon: Icon(_obscureText ? Icons.visibility_off: Icons.visibility),
onPressed: (){
setState(() {
_obscureText = !_obscureText;
});
Timer.run(() => myFocusNode2.unfocus());
},
)
),
),
What I have right now works, but it is not clean at all. Most of the time the text field becomes focused for a second then the .unfocus() unfocuses it after a delay, so I get this jump effect with the keyboard popping up and then going back down. Only a few times the text field will never get focused at all and I don't understand why.
Is there a way to make sure the IconButton never focuses the text field when it is pressed?
I just can think of 3 solutions, not prefect but just get the job done
1- use focusNode with timer
after you link foucsNode to the textfiled the button function could be something like this
onPressed: () {
Timer.periodic(Duration(microseconds: 1), (_) {
focusNode.unfocus();
});
//Write your code here
},
2- use stack
Stack(
alignment: Alignment.centerRight,
children: <Widget>[
TextField(
decoration: InputDecoration(
labelText: "Password",
border: OutlineInputBorder(),
),
),
IconButton(
icon: Icon(Icons.ac_unit),
onPressed: () {
//do any thing
},
),
],
),
3- as Afridi Kayal said you can use a row
Row(
children: <Widget>[
Expanded(
child: TextField(
focusNode: focusNode,
enabled: enabled,
autofocus: false,
textInputAction: TextInputAction.done,
decoration: InputDecoration(
labelText: "Password",
border: OutlineInputBorder(),
),
),
),
IconButton(
icon: Icon(Icons.visibility),
onPressed: () {
print('object');
},
),
],
),
if you end up going with number 2 or 3 and you want to make the button color change when you focus on the textfiled, you can do it by using focusNode as well.

Is it possible to show/hide textformfields in Flutter based on a Checkbox

I am trying to use a checkbox to show/hide 2 textformfields in Flutter. I have tried the below code thinking that it would use the state of the checkbox to display the fields. but this does not work.
The Checkbox itself does toggle between true and false but there is no change in the layout.
CheckboxListTile(
title: Text("Do you want to update your price?"),
controlAffinity: ListTileControlAffinity.leading,
value: priceupdate_value,
onChanged: (bool priceupdateValue) {
setState(() {
priceupdate_value = priceupdateValue;
});
if(priceupdate_value == true){
Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(
labelText: 'New Price',
),
),
TextFormField(
decoration: InputDecoration(
labelText: 'Update Other Information',
),
),
],
);
}
},
),
Wrap it with a visibility widget:
Visibility(
visible: priceupdate_value,
child: TextFormField(...),
)
And you have to create your Column Widget outside the onPressed Method (Like wrap your CheckBoxTileListWidget with a column Widget and then under children add Both your CheckBoxTileList and your TextInputField)
Something like
Column(
children: <Widget>[
Visibility(
visible: priceupdate_value,
child: TextFormField(
decoration: InputDecoration(
labelText: 'Update Other Information',
),
),
),
CheckBoxTileList(
title: Text("Do you want to update your price?"),
controlAffinity: ListTileControlAffinity.leading,
value: priceupdate_value,
onChanged: (bool priceupdateValue) {
setState(() {
priceupdate_value = priceupdateValue;
});
},
),
],
),
I did some small changes and it's ok.
I hope it will suit for you.
Column(
children: <Widget>[
if (priceupdate_value)
Column(
children: <Widget>[
TextFormField(
decoration: InputDecoration(
labelText: 'New Price',
),
),
TextFormField(
decoration: InputDecoration(
labelText: 'Update Other Information',
),
),
],
),
CheckboxListTile(
title: Text("Do you want to update your price?"),
controlAffinity: ListTileControlAffinity.leading,
value: priceupdate_value,
onChanged: (bool priceupdateValue) {
setState(() {
priceupdate_value = priceupdateValue;
});
},
),
],
),
You can copy-paste the code here to the dartpad.dev and check it instantly: https://gist.github.com/malibayram91/0ba5c3c5fbdb89f9c2a6a4ec3333d070

TextFormField Enable/Disable According to Radio Button checked Flutter

How can i Enable/Disable TextFormField According to radio button when checked in flutter ?
new Text('Allpages? :', style: new TextStyle(height: 1.0, fontSize: 15.2, fontWeight: FontWeight.bold,)),
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Radio(
value: 0,
groupValue: _printAllValue,
onChanged: _setPrintAllValue,
),
new Text('Yes'),
new Radio(
value: 1,
groupValue: _printAllValue,
onChanged: _setPrintAllValue,
),
new Text('No'),
],
),
new Padding(padding: new EdgeInsets.all(5.0)),
new Text('Start and End pages :', style: new TextStyle(height: 1.0, fontSize: 15.2, fontWeight: FontWeight.bold,)),
new Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Container(
width: 200,
child: new TextFormField(
style: TextStyle(color: Colors.black87),
textInputAction: TextInputAction.done,
keyboardType: TextInputType.phone,
decoration: InputDecoration(
labelText: 'Start Page',
),
),
),
new Container(
width: 200,
child: new TextFormField(
style: TextStyle(color: Colors.black87),
textInputAction: TextInputAction.done,
keyboardType: TextInputType.phone,
decoration: InputDecoration(
labelText: 'End Page',
),
),
),
],
),
new Padding(padding: new EdgeInsets.all(10.0)),
I need to 'Start Page', 'End Page' to be activated when check the No radio Button and deactivated when yes radio button checked
You can wrap your TextFormField inside AbsorbPointer and handle absorb property like:
bool _disable = false; // set this to false initially
AbsorbPointer(
absorbing: _disable, // true makes TextFormField disabled and vice-versa
child: TextFormField(),
)
Whenever you want to disable above field, you can change its property and actually fetch the value from your Radio and assign it to _disable
Edit:
There is a property in TextFormField, you can change that
TextFormField(
enabled: !_disable, // set to false to disable it.
),