Flutter 弹出键盘认识

13,299 阅读2分钟

Flutter中TextField使用

目的在于想找出键盘删除键的回调。于是有了下文:

TextField跟踪发现 在控件返回里面 有个_requestKeyboard() 这个函数:

//源码实现 
 void _requestKeyboard() {
    _editableTextKey.currentState?.requestKeyboard();
  }
  
//然后调用 requestKeyboard()
 void requestKeyboard() {
    if (_hasFocus)
      _openInputConnection();
    else
        //请求获取焦点
      FocusScope.of(context).requestFocus(widget.focusNode);
  }
  

也就是 在requestKeyboard()中,如果是有 _hasFocus == true 的时候就弹出键盘 ,(也就是获取到了焦点)。

// _openInputConnection ()打开软键盘
TextInputConnection _textInputConnection;
bool get _hasInputConnection => _textInputConnection != null && _textInputConnection.attached;

  void _openInputConnection() {
    if (!_hasInputConnection) {
      final TextEditingValue localValue = _value;
      _lastKnownRemoteTextEditingValue = localValue;
      _textInputConnection = TextInput.attach(this,
          TextInputConfiguration(
              inputType: widget.keyboardType,
              obscureText: widget.obscureText,
              autocorrect: widget.autocorrect,
              inputAction: widget.textInputAction ?? (widget.keyboardType == TextInputType.multiline
                  ? TextInputAction.newline
                  : TextInputAction.done
              ),
              textCapitalization: widget.textCapitalization,
          )
      )..setEditingState(localValue);
    }
    _textInputConnection.show();
  }
解析1 使用TextInputConnection 它的类需要实现 TextInputClient方法 然后重写:
//TextInputClient 抽象类的回调方法
@override
  void performAction(TextInputAction action) {
    // TODO: implement performAction
    //点击 键盘的 如图1 位置 这个按钮的点击回调
    print("  performAction  action $action ");
  }

  @override
  void updateEditingValue(TextEditingValue value) {
    // TODO: implement updateEditingValue
    //value文本输入内容回调  如 例子1 
    print("updateEditingValue  value  $value  ");
  }

图1

avatar
例子1 (键盘输入后回调内容)

TextEditingValue(text: ┤额度├, selection: TextSelection(baseOffset: 2, extentOffset: 2, affinity: TextAffinity.downstream, isDirectional: false), composing: TextRange(start: -1, end: -1))

解析2 TextInputConnection 关闭
//判断 _hasInputConnection 是否为空 或者是否已经绑定
void _closeInputConnectionIfNeeded() {
    if (_hasInputConnection) {
      _textInputConnection.close();
      _textInputConnection = null;
      _lastKnownRemoteTextEditingValue = null;
    }
  }
解析3 TextInputConnection 赋值 TextEditingValue
// value.toJSON(), 里面的值返回的是 json 
void setEditingState(TextEditingValue value) {
    assert(attached);
    SystemChannels.textInput.invokeMethod(
      'TextInput.setEditingState',
      value.toJSON(),
    );
  }
//远程更新数据在需要的时候
void _updateRemoteEditingValueIfNeeded() {
    if (!_hasInputConnection)
      return;
    final TextEditingValue localValue = _value;
    if (localValue == _lastKnownRemoteTextEditingValue)
      return;
    _lastKnownRemoteTextEditingValue = localValue;
    _textInputConnection.setEditingState(localValue);
  }

TextEditingValue .text 就可以获取到输入的值

解析4 TextInputConnection 中 setEditingState这个函数调用
/// Requests that the text input control change its internal state to match the given state.
  void setEditingState(TextEditingValue value) {
    assert(attached);
    print(" setEditingState ${value.text} ");
    SystemChannels.textInput.invokeMethod(
      'TextInput.setEditingState',
      value.toJSON(),
    );
  }

当控件获取焦点的时候调用此函数。

Future<dynamic> _handleTextInputInvocation(MethodCall methodCall) async {
    print(" _handleTextInputInvocation  MethodCall  ${methodCall.method} ");
    if (_currentConnection == null)
      return;
    final String method = methodCall.method;
    final List<dynamic> args = methodCall.arguments;
    final int client = args[0];
    // The incoming message was for a different client.
    if (client != _currentConnection._id)
      return;
    switch (method) {
      case 'TextInputClient.updateEditingState':
        _currentConnection._client.updateEditingValue(TextEditingValue.fromJSON(args[1]));
        break;
      case 'TextInputClient.performAction':
        _currentConnection._client.performAction(_toTextInputAction(args[1]));
        break;
      default:
        throw MissingPluginException();
    }
  }

上面函数打印得出 只有两个 状态 TextInputClient.updateEditingState 和 TextInputClient.performAction。

TextInputClient.updateEditingState 是获取焦点和内容改变都要调用

TextInputClient.performAction 这个是由点击 如图1 位置上的按钮 状态 才触发

由此得知 没有关于删除按键的监听 和回调。

键盘的类 在 包 import 'package:flutter/services.dart'; 下需要导入这个才能使用里面的类

其实我是想找出 删除键 的监听 看来是没有了。。。。至少功夫没有白费!