Держите клавиатуру открытой при временном отключении текстового поля

Как сохранить клавиатуру на экране при временном отключении текстового поля?

CupertinoTextField закрывает клавиатуру, когда enabled=false или readOnly=true. Мне нужно держать клавиатуру на экране.


person M. Leonhard    schedule 17.11.2019    source источник


Ответы (1)


Я искал около четырех часов и, наконец, нашел решение: сделать так, чтобы функция onChanged текстового поля фокусировала скрытый виджет, который принимает ввод с клавиатуры. После завершения обработки снова сфокусируйте текстовое поле.

Рабочий пример:

import 'package:flutter/cupertino.dart'
    show
        CupertinoApp,
        CupertinoButton,
        CupertinoPageScaffold,
        CupertinoTextField;
import 'package:flutter/widgets.dart'
    show
        BuildContext,
        Center,
        ClipRect,
        Column,
        Container,
        FocusNode,
        FocusScope,
        MainAxisSize,
        runApp,
        State,
        StatefulWidget,
        Text,
        TextAlign,
        TextEditingController,
        Widget;
import 'package:meta/meta.dart' show required;

class KeepKeyboardOnScreen extends StatefulWidget {
  final FocusNode focusNode;

  const KeepKeyboardOnScreen({@required this.focusNode});

  @override
  State createState() => KeepKeyboardOnScreenState();
}

class KeepKeyboardOnScreenState extends State<KeepKeyboardOnScreen> {
  TextEditingController _controller;

  @override
  void initState() {
    super.initState();
    _controller = new TextEditingController();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) => Container(
        height: 0,
        child: ClipRect(
          child: CupertinoTextField(
            controller: _controller,
            focusNode: widget.focusNode,
            onChanged: (_) => _controller.clear(),
          ),
        ),
      );
}

class Page extends StatefulWidget {
  @override
  State createState() => PageState();
}

class PageState extends State<Page> {
  TextEditingController _controller;
  FocusNode _focusNode;
  FocusNode _keepKeyboardOnScreenFocusNode;
  bool enabled = true;

  @override
  void initState() {
    super.initState();
    _controller = new TextEditingController();
    _focusNode = new FocusNode();
    _keepKeyboardOnScreenFocusNode = new FocusNode();
  }

  @override
  void dispose() {
    _controller.dispose();
    _focusNode.dispose();
    _keepKeyboardOnScreenFocusNode.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) => CupertinoApp(
        home: CupertinoPageScaffold(
          child: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                CupertinoTextField(
                  controller: _controller,
                  focusNode: _focusNode,
                  enabled: enabled,
                ),
                KeepKeyboardOnScreen(focusNode: _keepKeyboardOnScreenFocusNode),
                CupertinoButton(
                    onPressed: () {
                      setState(() {
                        enabled = true;
                      });
                      FocusScope.of(context).requestFocus(_focusNode);
                    },
                    child: Text("Enable", textAlign: TextAlign.center)),
                CupertinoButton(
                    onPressed: () {
                      setState(() {
                        enabled = false;
                      });
                      FocusScope.of(context)
                          .requestFocus(_keepKeyboardOnScreenFocusNode);
                    },
                    child: Text("Disable", textAlign: TextAlign.center)),
              ],
            ),
          ),
        ),
      );
}

void main() async {
  runApp(Page());
}

См. также: Flutter Issue #45076 Добавьте документацию высокого уровня и примеры по управлению фокусом клавиатуры.

person M. Leonhard    schedule 17.11.2019
comment
Будет ли этот подход сохранять текущий тип клавиатуры? - person Sebastian Roth; 03.12.2020
comment
Конструктор CupertinoTextField принимает параметр keyboardType, который по умолчанию равен TextInputType.text. Flutter показывает эту клавиатуру, когда фокусирует скрытый виджет. Если отображается другая клавиатура, она переключится на эту клавиатуру. Чтобы сохранить другую клавиатуру на экране, вы должны передать соответствующее значение keyboardType. - person M. Leonhard; 04.01.2021