1. 程式人生 > >Flutter 彈出鍵盤認識

Flutter 彈出鍵盤認識

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 local
Value = _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(local
Value); } _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'; 下需要匯入這個才能使用裡面的類

其實我是想找出 刪除鍵 的監聽 看來是沒有了。。。。至少功夫沒有白費!