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?
13 Answers
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.
Here's what it looks like when it's enabled.
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',
),
),
),
),
),
);
}
}
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.
This is another way of somehow disabling a TextField but keeping it's functionality. I mean for onTap usage
TextField(
enableInteractiveSelection: false,
onTap: () { FocusScope.of(context).requestFocus(new FocusNode()); },
)
enableInteractiveSelectionwill disable content selection of
TextFieldFocusScope.of(context).requestFocus(new FocusNode());change the focus to an unused focus node
Using this way, you can still touch TextField but can't type in it or select it's content. Believe me it's going to be useful sometimes ( datepicker, timepicker, ... ) :)
There is now a way to disable TextField and TextFormField. See github here.
Use it like this:
TextField(enabled: false)
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.
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
);
Use readOnly: true
TextField(
readOnly: true,
controller: controller,
obscureText: obscureText,
onChanged: (value) {
onValueChange();
},
style: TextStyle(
color: ColorResource.COLOR_292828,
fontFamily: Font.AvenirLTProMedium.value,
fontSize: ScreenUtil().setHeight(Size.FOURTEEN)),
decoration: InputDecoration(
border: InputBorder.none,
hintText: hint,
hintStyle: TextStyle(
fontSize: ScreenUtil().setHeight(Size.FOURTEEN),
color: ColorResource.COLOR_HINT,
fontFamily: Font.AvenirLTProBook.value)),
),



