Flutter 自定义键盘(“假”软键盘)

Posted

技术标签:

【中文标题】Flutter 自定义键盘(“假”软键盘)【英文标题】:Flutter Custom Keyboard ('Fake' soft keyboard) 【发布时间】:2019-01-05 01:48:20 【问题描述】:

我正在开发一个金融应用程序,我想要一个自定义文本输入字段和键盘,用于使用内置计算器输入货币。

我尝试过使用 BottomSheet,包括持久性和模态。模态行为是理想的,但它总是显示出障碍。持久的就是我现在拥有的,使用焦点节点来显示和隐藏它,但它会抛出奇怪的错误:

I/flutter (30319): The following NoSuchMethodError was thrown while dispatching notifications for FocusNode:
I/flutter (30319): The method 'removeLocalHistoryEntry' was called on null.
I/flutter (30319): Receiver: null
I/flutter (30319): Tried calling: removeLocalHistoryEntry(Instance of 'LocalHistoryEntry')
I/flutter (30319):
I/flutter (30319): When the exception was thrown, this was the stack:
I/flutter (30319): #0      Object.noSuchMethod (dart:core/runtime/libobject_patch.dart:46:5)
I/flutter (30319): #1      LocalHistoryEntry.remove (package:flutter/src/widgets/routes.dart:296:12)
I/flutter (30319): #2      _NumpadFieldState.initState.<anonymous closure> (file:///D:/code/financepie/lib/widgets/numpad/numpadfield.dart:30:32)
...

无论如何,底部的工作表行为(向下拖动)对于复制 android/ios 软键盘并不是很理想。有更好的解决方案吗?当前代码如下:

import 'package:flutter/material.dart';
import 'numpad.dart';

class NumpadField extends StatefulWidget 

  @override
  _NumpadFieldState createState() 
    return new _NumpadFieldState();
  


class _NumpadFieldState extends State<NumpadField> 
  ValueNotifier<List<String>> state;
  FocusNode focusNode;
  PersistentBottomSheetController bottomSheetController;

  @override initState() 
    super.initState();
    state = ValueNotifier<List<String>>([]);
    state.addListener(() => setState(()));
    focusNode = FocusNode();
    focusNode.addListener(() 
      print(focusNode);
      if (focusNode.hasFocus) 
        bottomSheetController = showBottomSheet(
          context: context,
          builder: (context) => Numpad(state: state),
        );
       else 
        bottomSheetController?.close(); ///this line causing the error
      
    ); 
  
  @override dispose() 
    state.dispose();
    focusNode.dispose();
    super.dispose();
  

  @override
  Widget build(BuildContext context) 
    return GestureDetector(
      onTap: () 
        FocusScope.of(context).requestFocus(focusNode);
      ,
      child: Container(
        child: Text(state.value.fold<String>("", (str, e) => "$str $e")),
        constraints: BoxConstraints.expand(height: 24.0),
        decoration: BoxDecoration(
          border: BorderDirectional(bottom: BorderSide())
        ),
      ),
    );
  

【问题讨论】:

我认为您不应该为此使用底页。您可以将其集成到您的布局中或使用an Overlay(我链接的内容只是您的起点)。 @creativecreatorormaybenot 我认为你是对的。一个想法 - 我可以使用 ModalRoute 吗?键盘打开时,“背景”路由中的文本字段会更新吗? 我已尝试运行您的,但系统在import 'numpad.dart'; 中检测到错误。您能否提供有关该特定导入的更多背景信息?它是您创建的插件还是单独的类? 是键盘实现。但是最后我用了一个覆盖或类似的东西,怕我现在不记得了 你能在这里分享你的解决方案吗? 【参考方案1】:

bottomSheetController?.close(); 可以为空。由于该行导致错误,您可以添加一个空检查来防止此问题。

else 
  if(bottomSheetController != null)
      bottomSheetController!.close();

【讨论】:

以上是关于Flutter 自定义键盘(“假”软键盘)的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 124: 日常问题小结 (三) 自定义 Dialog 二三事

Android自定义软键盘

启动自定义软键盘后文本字段不显示光标

在自定义适配器中隐藏软键盘

Flex 自定义皮肤不调出 IOS 软键盘

在 Android 自定义键盘中检测 isSticky