I need to disable TextFormField occasionally. I couldn\'t find a flag in the widget, or the controller to simply make it read only or disable. What is the best way to do it?
This isn't a feature that is currently provided by the framework, but you can use a FocusScope to prevent a TextFormField
from requesting focus.
Here's what it looks like when it's disabled.
(with hint text)
(with a readonly value)
Here's what it looks like when it's enabled.
(with focus)
(without focus)
Code for this is below:
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new HomePage(),
));
}
class HomePage extends StatefulWidget {
HomePageState createState() => new HomePageState();
}
class HomePageState extends State<HomePage> {
TextEditingController _controller = new TextEditingController();
bool _enabled = false;
@override
Widget build(BuildContext context) {
ThemeData theme = Theme.of(context);
return new Scaffold(
appBar: new AppBar(
title: new Text('Disabled Text'),
),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.free_breakfast),
onPressed: () {
setState(() {
_enabled = !_enabled;
});
}
),
body: new Center(
child: new Container(
margin: const EdgeInsets.all(10.0),
child: _enabled ?
new TextFormField(controller: _controller) :
new FocusScope(
node: new FocusScopeNode(),
child: new TextFormField(
controller: _controller,
style: theme.textTheme.subhead.copyWith(
color: theme.disabledColor,
),
decoration: new InputDecoration(
hintText: _enabled ? 'Type something' : 'You cannot focus me',
),
),
),
),
),
);
}
}
I tried using FocuseNode(), enabled = false yet not working, Instead of that I use a widget called AbsorbPointer. It's use for preventing a widget from touch or tap, I wrap my TextFormField or other widget inside AbsordPointer Widgets and give a parameter to disable from touch
Example
AbsorbPointer(
absorbing: true, //To disable from touch use false while **true** for otherwise
child: Your WidgetsName
);
There is another way this can be achieved which also does not cause this issue. Hope this might help someone.
Create AlwaysDisabledFocusNode
and pass it to the focusNode
property of a TextField
.
class AlwaysDisabledFocusNode extends FocusNode {
@override
bool get hasFocus => false;
}
then
new TextField(
enableInteractiveSelection: false, // will disable paste operation
focusNode: new AlwaysDisabledFocusNode(),
...
...
)
Update:
TextField
now has enabled
property. Where you can just disable the TextField
like
new TextField(
enabled: false,
...
...
)
Note: This will also disable icon associated with text input.
Use readOnly:true
is correct. But if you still want focus to this text field you can follow below code:
TextFormField(
showCursor: true,//add this line
readOnly: true
)
I have used a combination of readOnly and enableInteractiveSelection properties to achieve the desired behavior on TextField.
TextField(
readOnly: true,
enableInteractiveSelection: true,
onTap: () {
do_something(),
},
)
With enableInteractiveSelection set to true, it will allow onTap() to function as normal.