Flutter teclado emergente y supervisión cercana

Problemas de encuentro

Encontré un problema al usar el control de código de verificación PinCodeField . En Android, tocar hacia atrás o tocar el teclado de cierre en la esquina superior derecha del teclado no hará que PinCodeField pierda el enfoque, por lo que después de cerrar el teclado, PinCodeField ha estado en un estado de obtención de enfoque y no puede Haga clic de nuevo para que PinCodeField obtenga el foco para que aparezca el teclado, por lo que tenemos que monitorear la ventana emergente y el cierre del teclado para establecer el estado de enfoque correspondiente.

solución

El primer uso de la biblioteca de terceros keyboard_visibility

keyboard_visibility teclado emergente monitorización cercana

Este desarrollador no lo ha actualizado durante mucho tiempo, así que extraje el código localmente para poder modificarlo yo mismo cuando no sea compatible.

Si se usa, prevalecerá la dependencia local. Colóquelo en el mismo directorio que nuestro proyecto principal y use el siguiente método para depender de:

keyboard_visibility:
    path: ../flutter_keyboard_visibility

utilizar:

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();
  }

Si encuentra los siguientes problemas al usar la versión anterior del autor:

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.

Cambie compileSdkVersion en build.gradle en el directorio keyboard_visibility de 27 a 28:
Inserte la descripción de la imagen aquí

Keyboard_visibility se usa en detalle, esta biblioteca de bifurcaciones ya se ha ocupado de los problemas anteriores

El segundo uso WidgetsBindingObserver y didChangeMetrics

El componente WidgetsBindingObserver puede monitorear algunos ciclos de vida de la página, y hay una devolución de llamada didChangeMetrics que puede monitorear los cambios en la altura de la interfaz. Entre ellos, las ventanas emergentes y desplegables del teclado son en realidad cambios de altura y, naturalmente, se pueden monitorear.

utilizar:

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();
  }

El uso específico en combinación con PinCodeTextField es el siguiente:

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);
    }
  }
}

Referencia: el teclado Flutter aparece y cierra la monitorización

Supongo que te gusta

Origin blog.csdn.net/u011148116/article/details/106902318
Recomendado
Clasificación