首页 > 解决方案 > 暂时禁用文本字段时保持键盘打开

问题描述

如何在暂时禁用文本字段的同时保持键盘在屏幕上?

CupertinoTextFieldenabled=false在或时关闭键盘readOnly=true。我需要将键盘保持在屏幕上。

标签: fluttermobilesoft-keyboard

解决方案


我搜索了大约四个小时,终于想出了一个解决方案:让文本字段的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 问题 #45076 添加有关管理键盘焦点的高级文档和示例。


推荐阅读