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?


Solution 1: Collin Jackson

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) empty and readonly

(with a readonly value) readonly

Here's what it looks like when it's enabled.

(with focus) focused

(without focus) editable

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


Solution 2: Hemanth Raj

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.


Solution 3: Vikas

TextField and TextFormField both have an argument called enabled. You can control it using a boolean variable. enabled=true means it will act as an editing text field whereas enabled=false will disable the TextField.


Solution 4: Pars

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

    will disable content selection of TextField

  • FocusScope.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, ... ) :)


Solution 5: Benten

There is now a way to disable TextField and TextFormField. See github here. Use it like this:

TextField(enabled: false)


Solution 6: JChen___

Similar to readonly like in html

TextField(
    enableInteractiveSelection: false,
    focusNode: FocusNode(),
)

This can response to onTap.


Similar to disabled like in html

TextField(
    enable: false
)

This can not response to onTap.


Solution 7: Peter Adepojú

TextFormField(
readOnly: true,
)


Solution 8: SilenceCodder

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


Solution 9: gowthaman C

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


Solution 10: 1DD

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.


Solution 11: Doan Bui

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
)

And if you want hide text pointer (cursor), you need set enableInteractiveSelection to false.


Solution 12: Manoj Perumarath

It has enabled key, this is doing fine for me.

TextFormField(
    enabled: false,
)


Solution 13: Rostyslav N

Remove native keyboard then focus TextField programmaticaly (for example, after click emoji button):

FocusScope.of(context).requestFocus(titleFocusNode);
titleFocusNode.consumeKeyboardToken();


Solution 14: Toufiqul Haque Mamun

It's working for me

TextField(
          readOnly: true,
         onChanged: (value) { },
        )


Solution 15: Andrew Amin

For that... TextField has two properties:

TextField(
          readOnly: true,
          enabled: false,
        )

1- If you desire to disable the TextField typing and taping set [enabled: false]

2- If you desire to disable only TextField typing set [readOnly: true]


Solution 16: Mini Titan

TextField
(
enable: false
)

Or

TextFormField(
    enable: false
)

if you use InputDecoration don't forget to set disabledBorder like this

TextFormField(
      enabled: false,
      decoration: InputDecoration(
        enabledBorder: OutlineInputBorder(
          borderRadius: BorderRadius.circular(10.0),
          borderSide: BorderSide(color: Colors.blue),
        ),
        disabledBorder:  OutlineInputBorder(
          borderRadius: BorderRadius.circular(10.0),
          borderSide: BorderSide(color: Colors.gray),
        ),
        filled: true,
      ),
    );