Flutter keyboard pop-up and close monitoring

Encounter problems

I encountered a problem when using the PinCodeField verification code control . On Android, tapping back or tapping the close keyboard in the upper right corner of the keyboard will not trigger PinCodeField to lose focus, so after closing the keyboard, PinCodeField has been in a state of obtaining focus and cannot Click again to make PinCodeField get the focus to pop up the keyboard, so we have to monitor the pop-up and close of the keyboard to set the corresponding focus state.

solution

The first use keyboard_visibility third party library

keyboard_visibility keyboard pop-up close monitoring

This developer hasn't updated it for a long time, so I pulled the code locally so that I can modify it myself when it is not compatible.

If used, the local dependency shall prevail. Put it in the same directory as our main project and use the following method to depend on:

keyboard_visibility:
    path: ../flutter_keyboard_visibility

use:

import 'package:keyboard_visibility/keyboard_visibility.dart';


 int subscribeId;

 @protected
 void initState() {
   super.initState();
   subscribeId = KeyboardVisibilityNotification().addNewListener(
     onChange: (bool visible) {
       print(visible);
     },
   );
 }

 //及时移除防止内存泄漏问题 "A LoginInputCodeViewModel was used after being disposed."
 @override
  void dispose() {
    KeyboardVisibilityNotification().removeListener(subscribeId);
    super.dispose();
  }

If you encounter the following problems while using the author’s old version:

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':keyboard_visibility:verifyReleaseResources'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
   > 1 exception was raised by workers:
     com.android.builder.internal.aapt.v2.Aapt2Exception: Android resource linking failed
     C:\Users\Administrator\.gradle\caches\transforms-2\files-2.1\da95e0dd41fd0c634661df2a0f122634\core-1.1.0\res\values\values.xml:142:5-173:25: AAPT: error: resource android:attr/fontVariationSettings not found.

     C:\Users\Administrator\.gradle\caches\transforms-2\files-2.1\da95e0dd41fd0c634661df2a0f122634\core-1.1.0\res\values\values.xml:142:5-173:25: AAPT: error: resource android:attr/ttcIndex not found.

Please change the compileSdkVersion in build.gradle in the keyboard_visibility directory from 27 to 28:
Insert picture description here

Keyboard_visibility is used in detail, this fork library has already dealt with the above problems

The second use WidgetsBindingObserver & didChangeMetrics

The WidgetsBindingObserver component can monitor some life cycles of the page, and there is a callback didChangeMetrics that can monitor changes in the interface height. Among them, the pop-up and fold-out of the keyboard are actually height changes and can naturally be monitored.

use:

class _PinCodeTextFieldState extends State<PinCodeTextField> with WidgetsBindingObserver {

  bool isKeyboardActived = false;

 @protected
void initState() {
 //根据autoFocus赋予isKeyboardActived初值,自动获取焦点的话键盘是自动弹出的需要赋值为true正好和autoFocus对应
 isKeyboardActived = widget.autoFocus;
 WidgetsBinding.instance.addObserver(this);
   super.initState();
}

@override
  void didChangeMetrics() {
    super.didChangeMetrics();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      // 当前是安卓系统并且在焦点聚焦的情况下
      if (Platform.isAndroid && _focusNode.hasFocus) {
        if (isKeyboardActived) {
          isKeyboardActived = false;
          // 使输入框失去焦点
          _focusNode.unfocus();
          return;
        } else {
//          showToast("键盘弹出 false");
        }
        isKeyboardActived = true;
      } else {
        isKeyboardActived = false;
//        showToast("键盘消失");
      }
    });
  }

 @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

The specific use in combination with PinCodeTextField is as follows:

class PinCodeTextField extends StatefulWidget {
 
  /// If the pin code field should be autofocused or not. Default is [false]
  final bool autoFocus;

  /// Should pass a [FocusNode] to manage it from the parent
  final FocusNode focusNode;

  PinCodeTextField({
    Key key,
    //省略代吗...
    this.autoFocus = false,
    this.focusNode,
	//省略代吗...
  }) : super(key: key);
}

class _PinCodeTextFieldState extends State<PinCodeTextField>
    with WidgetsBindingObserver {//重点
  FocusNode _focusNode;
  bool isKeyboardActived = false;

  @override
  void initState() {
	 //重点
    isKeyboardActived = widget.autoFocus;
    //重点
    WidgetsBinding.instance.addObserver(this);
    _focusNode = widget.focusNode ?? FocusNode();
    _focusNode.addListener(() {
      setState(() {});
    }); 
    super.initState();
  }

  // validating all the values
  void _checkForInvalidValues() {
   //省略代吗...
  }


  @override
  void dispose() {
    _textEditingController.dispose();
    _focusNode.dispose();
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }


  @override
  Widget build(BuildContext context) {
    return Stack(
    	//省略代吗...
        GestureDetector(
          onTap: _onFocus,
        	//省略代吗...
          child: Container(
            //省略代吗...
          ),
        ),
      ],
    );
  }
   //重点
  @override
  void didChangeMetrics() {
    super.didChangeMetrics();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      // 当前是安卓系统并且在焦点聚焦的情况下
      if (Platform.isAndroid && _focusNode.hasFocus) {
        if (isKeyboardActived) {
          isKeyboardActived = false;
          // 使输入框失去焦点
          _focusNode.unfocus();
          return;
        } else {
//          showToast("键盘弹出 false");
        }
        isKeyboardActived = true;
      } else {
        isKeyboardActived = false;
//        showToast("键盘消失");
      }
    });
  }
 //重点
  void _onFocus() {
    if (_focusNode.hasFocus) {
//      showToast("点击 hasFocus");
      _focusNode.unfocus();
    } else {
//      showToast("点击 noFocus");
      FocusScope.of(context).requestFocus(_focusNode);
    }
  }
}

Reference: Flutter keyboard pops up and closes monitoring

Guess you like

Origin blog.csdn.net/u011148116/article/details/106902318