Отключить поле редактирования текста во флаттере

Иногда мне нужно отключать TextFormField. Я не смог найти ни флага в виджете, ни контроллера, чтобы просто сделать его доступным только для чтения или отключить. Как лучше всего это сделать?


person Arash    schedule 12.06.2017    source источник
comment
Создан github.com/flutter/flutter/issues/10645   -  person Seth Ladd    schedule 13.06.2017
comment
Для людей из Google теперь вы можете добавить флаг на виджет, см. Мой ответ.   -  person Benten    schedule 12.03.2019
comment
@Arash, можете ли вы изменить принятый ответ на один из последних, потому что фреймворк теперь поддерживает это   -  person geg    schedule 16.10.2020


Ответы (12)


Эта функция в настоящее время не предоставляется платформой, но вы можете использовать FocusScope, чтобы TextFormField не запрашивал фокус.

Вот как это выглядит в отключенном состоянии.

(с текстом подсказки)  empty and readonly

(со значением только для чтения)  только для чтения

Вот как это выглядит, когда он включен.

(с фокусом)  сфокусировано

(без фокуса)  editable

Код для этого ниже:

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',
              ),
            ),
          ),
        ),
      ),
    );
  }
}
person Collin Jackson    schedule 12.06.2017
comment
не нужно это добавлять? FocusScopeNode(canRequestFocus: _enabled, child: ..... - person J. MARS; 23.06.2021

Это может быть достигнуто другим способом, который также не вызывает этой проблемы. Надеюсь, это может кому-то помочь.

Создайте AlwaysDisabledFocusNode и передайте его свойству focusNode объекта TextField.

class AlwaysDisabledFocusNode extends FocusNode {
  @override
  bool get hasFocus => false;
}

тогда

new TextField(
    enableInteractiveSelection: false, // will disable paste operation
    focusNode: new AlwaysDisabledFocusNode(),
    ...
    ...
)

Обновление: TextField теперь имеет свойство enabled. Где можно просто отключить TextField лайк

new TextField(
    enabled: false, 
    ...
    ...
)

Примечание. Это также отключит значок, связанный с вводом текста.

person Hemanth Raj    schedule 12.02.2018
comment
Да, у вас может быть TextFormatter, который игнорирует любой ввод (через вставку), но возвращает исходный код, чтобы избежать такого поведения :) - person Hemanth Raj; 24.01.2019
comment
Я нашел более простой вариант, в моем случае я использовал ваше решение и просто проигнорировал всплывающее окно, предлагающее вставить, используя enableInteractiveSelection: false для TextField;) - person MoGa; 24.01.2019
comment
enable = false; не отправляет событие onTap (). Я хочу, чтобы он был отключен и не фокусировался, но я не хочу, чтобы он был мертв. Я хочу контролировать это. Он все равно должен запускать onTap (), если установлен. Даже если обернуть его в GestureDetector. Чувак, этот трепет иногда может разочаровывать ... - person Dpedrinha; 21.11.2019
comment
@Dpedrinha, почему бы не использовать мое первое решение, AlwaysDisabledFocusNode? - person Hemanth Raj; 21.11.2019
comment
@HemanthRaj Я тоже пробовал. Я не помню, в чем проблема, но она также мешала некоторому желаемому поведению. - person Dpedrinha; 22.11.2019

TextField и TextFormField имеют аргумент enabled. Вы можете управлять им с помощью логической переменной. enabled=true означает, что он будет действовать как текстовое поле для редактирования, тогда как enabled=false отключит TextField.

person Vikas    schedule 29.05.2018
comment
Это реальный ответ. - person Hahnemann; 25.07.2018
comment
Это зависит от ваших потребностей. Оба решают проблему, но решение Hemanth Raj не отключает значок, связанный с вводом текста (наложите серый цвет на вашу тему accentColor), который может сказать пользователю, что ему нечего завершать (возможно, вы хотите, чтобы пользователь щелкнул модальный и заполните это поле значениями по умолчанию). Для простого отключения ввода ответ Викаса Панди должен быть принятым. - person Matias; 26.07.2018
comment
Это настоящий ответ! - person Aryeetey Solomon Aryeetey; 24.01.2019
comment
проблема с enabled=false в том, что он предотвращает появление сообщения об ошибке - person Mohamed Ali; 22.03.2019
comment
enabled = false ничего не делает - person Nijat Mursali; 24.04.2021
comment
Это тот ответ, который я хотел. Просто и прочно - person Geono; 09.05.2021

Подобно только для чтения, как в html

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

Это может быть ответ на onTap.


Похоже на отключено, как в html

TextField(
    enable: false
)

Это не может ответить на onTap.

person JChen___    schedule 20.03.2019
comment
Это именно то, что мне нужно для ввода в календарь. Спасибо! - person dmarquina; 10.04.2019

Это еще один способ каким-то образом отключить TextField, но сохранить его функциональность. Я имею в виду onTap использование

TextField(
    enableInteractiveSelection: false,
    onTap: () { FocusScope.of(context).requestFocus(new FocusNode()); },
)
  • enableInteractiveSelection

    отключит выбор содержимого для TextField

  • FocusScope.of(context).requestFocus(new FocusNode());

    изменить фокус на неиспользуемый узел фокуса

Таким образом вы по-прежнему можете касаться TextField, но не можете вводить текст или выбирать его содержимое. Поверьте, иногда это будет полезно (datepicker, timepicker, ...) :)

person Pars    schedule 17.01.2019
comment
Это именно то, что я искал. Спасибо - person dewashish upadhyay; 13.12.2020
comment
Спасибо, это работает для меня. - person Ankit Saini; 29.01.2021

Использование readOnly:true правильно. Но если вы все еще хотите сосредоточиться на этом текстовом поле, вы можете следовать приведенному ниже коду:

TextFormField(
  showCursor: true,//add this line
  readOnly: true
)

А если вы хотите скрыть текстовый указатель (курсор), вам нужно установить enableInteractiveSelection в false.

person Doan Bui    schedule 26.11.2020

Теперь есть способ отключить TextField и TextFormField. См. Github здесь. Используйте это так:

TextField(enabled: false)
person Benten    schedule 12.03.2019
comment
наверное лучший ответ, интересно, почему он не проголосовал - person omidh; 26.05.2021

Я использовал комбинацию свойств readOnly и enableInteractiveSelection для достижения желаемого поведения в TextField.

TextField(
  readOnly: true,
  enableInteractiveSelection: true,
  onTap: () {
    do_something(),
  },
)

Если для enableInteractiveSelection установлено значение true, это позволит onTap () работать как обычно.

person 1DD    schedule 30.07.2020
comment
Это лучший ответ! Большое спасибо! - person ulusoyca; 28.10.2020
comment
в функции onTap попробуйте использовать FocusScope.of (context) .unfocus (); он отключит режим записи - person Rohan; 27.07.2021

Я пробовал использовать FocuseNode (), enabled = false, но не работал. Вместо этого я использую виджет под названием AbsorbPointer. Он используется для предотвращения касания или касания виджета, я оборачиваю свой TextFormField или другой виджет внутри виджетов AbsordPointer и даю параметр для отключения от прикосновения

Пример

AbsorbPointer(
      absorbing: true,  //To disable from touch use false while **true** for otherwise
      child: Your WidgetsName
);
person SilenceCodder    schedule 04.09.2019

Используйте 1_

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)),
  ),
person gowthaman C    schedule 28.07.2020

У него есть enabled ключ, меня это устраивает.

TextFormField(
    enabled: false,
)
person Manoj Perumarath    schedule 01.06.2021

person    schedule
comment
Чтобы создать более надежный ответ, вы должны добавить некоторый контекст того, что делает ваш код. Для получения дополнительной помощи см. как ответить. - person technogeek1995; 24.07.2019
comment
Это то, что я ищу, enabled: false отключает кнопку значка суффикса (я использую значок content_copy для копирования). Но этот работает - person mirkancal; 16.08.2019
comment
Есть проблема с readOnly: true - когда пользователь выбирает этот элемент управления - появляются синие границы, что в основном означает, что он позволяет сфокусироваться на элементе управления. - person abhijat_saxena; 07.09.2020