Flutter页面在软键盘弹出的时候,可以设置 Scaffold 的 resizeToAvoidBottomInset 属性来设置软键盘的处理。

当这个值为true的时候,页面会进行重新布局。那么我们应该如何监听 Flutter 的键盘弹出和页面的高度变化?

我们从 Flutter 键盘弹出说起。当一个输入框 TextField 的焦点变化的时候,焦点变化会执行
_openOrCloseInputConnectionIfNeeded 方法:

if (_hasFocus && widget.focusNode.consumeKeyboardToken()) {
      _openInputConnection();
    } else if (!_hasFocus) {
      _closeInputConnectionIfNeeded();
      widget.controller.clearComposing();
    }

这里会调用 TextInputConnection 的 show 方法打开键盘:

void _show() {
    _channel.invokeMethod<void>('TextInput.show');
  }

这里会通过 _show 的调用,去调 TextInput.show 这个方法

// android 端实现
mImm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);

// TextInputHandler
private void showTextInput(View view) {
    view.requestFocus();
    mImm.showSoftInput(view, 0);
 }

在Android 端,最后是调用 InputMethodManager 来打开软键盘。这里的 view 指的就是 FlutterView 。

此时 View 的 onApplyWindowInsets 会被调用:

// FlutterView
mMetrics.physicalViewInsetBottom =
          navigationBarVisible
              ? insets.getSystemWindowInsetBottom()
              : guessBottomKeyboardInset(insets);

updateViewportMetrics();


private int guessBottomKeyboardInset(WindowInsets insets) {
    int screenHeight = getRootView().getHeight();
    // Magic number due to this being a heuristic. This should be replaced, but we have not
    // found a clean way to do it yet (Sept. 2018)
    final double keyboardHeightRatioHeuristic = 0.18;
    if (insets.getSystemWindowInsetBottom() < screenHeight * keyboardHeightRatioHeuristic) {
      // Is not a keyboard, so return zero as inset.
      return 0;
    } else {
      // Is a keyboard, so return the full inset.
      return insets.getSystemWindowInsetBottom();
    }
  }

这里我们可以看到,在 Android 端,软键盘的高度在底部栏可见的时候取的就是系统 window inset 的 bottom。

如果不可见,就会根据 bottom inset 的占比去猜测。当这个高度大于 0.18 的时候,就会认为是键盘弹出。

当判断是软键盘后,会通过刷新 ViewportMetrics 来触发页面重绘:

// FlutterView
private void updateViewportMetrics() {
	if (!isAttached()) return;

	mNativeView
		.getFlutterJNI()
        .setViewportMetrics(
            mMetrics.devicePixelRatio,
            mMetrics.physicalWidth,
            mMetrics.physicalHeight,
            mMetrics.physicalPaddingTop,
            mMetrics.physicalPaddingRight,
            mMetrics.physicalPaddingBottom,
            mMetrics.physicalPaddingLeft,
            mMetrics.physicalViewInsetTop,
            mMetrics.physicalViewInsetRight,
            mMetrics.physicalViewInsetBottom,
            mMetrics.physicalViewInsetLeft,
            mMetrics.systemGestureInsetTop,
            mMetrics.systemGestureInsetRight,
            mMetrics.systemGestureInsetBottom,
            mMetrics.systemGestureInsetLeft);
}

metrics 更新在 Dart 端的入口在 hooks.dart 中

@pragma('vm:entry-point')
void _updateWindowMetrics(
  	//...省略参数
) {
	_invoke(window.onMetricsChanged, window._onMetricsChangedZone);

}

经过上面的理论分析,我们可以得出结论,Flutter 软键盘的高度变化体现在 metrics  的变化。具体的值,则体现在 window.viewInsets.bottom 中。

总结

到此这篇关于Flutter软键盘原理的文章就介绍到这了,更多相关Flutter软键盘原理内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Flutter软键盘的原理浅析的更多相关文章

  1. Swift开发教程--UITextField输入框如何隐藏软键盘

    对于UITextField如何隐藏输入框,一直是初学者常遇到的问题。在View试图中,点击选中UITextField控件,为其添加DidEndOnExit实践。在弹出软键盘之后,点击return就可以隐藏软键盘了。

  2. swift学习SayHiApp

    新建iOSsingleviewapplication名字为SayHiApp,打开mainstoryboard选中viewcontrooler,右上角,attributeinspector中simulatedmetrics的size选择iphone4.7-inch这样viewcontroller更像是一个iphone..然后拖动三个控件到界面上lable,textfield,button最后打开as

  3. Flutter中文教程-Cookbook

    Flutter中文网的Cookbook中包含了在编写Flutter应用程序时常见问题及示例。设计基础使用主题共享颜色和字体样式Images显示来自网上的图片用占位符淡入图片使用缓存图Lists创建一个基本list创建一个水平list使用长列表创建不同类型子项的List创建一个gridList处理手势处理点击添加Material触摸水波效果实现滑动关闭导航导航到新页面并返回给新页面传值从新页面返回数据给上一个页面网络从网上获取数据进行认证请求使用WebSockets

  4. android – 没有EditText和检测按键的软键盘

    如何使用硬键盘或软键盘可靠地检测按键?解决方法那你可以覆盖[onKeyDown][1]和(或)[onKeyUp][2]应用程序活动类中的方法,这将允许您获得有关诸如后退密钥和其他硬件密钥等密钥的通知……

  5. Android的Keycode最小化软键盘按钮

    我正在使用Android3.2的软键盘.问题是我无法找到左下角按钮的keyCode,以最小化键盘.我使用onKeyDown的switchcase来显示keyCode,它似乎是唯一没有值的.我认为它将具有与后退按钮相同的代码,因为它取代了它,但没有这样的运气.解决方法它只是后退按钮.您可以通过覆盖其行为来实现此目的:并且:

  6. android-studio – 未配置Dart SDK

    Initializinggradle…

  7. 如何在Android中的片段中完美展示软键盘?

    解决方法这是我使用的代码,它在Fragments中运行得非常好

  8. 安卓 – 从一个扑动的应用程序拨打电话

    或者有更好的选择从我的应用程序拨打电话?

  9. android – 按下回车键时保持软键盘打开

    好吧,当用户在编辑文本字段后按“确定”按钮时,我试图阻止软键盘关闭.实际上,我想要实现的是:当按下“ok”按钮时,将解析该字段,如果有效,则启动另一个活动.这很容易.但是,当该字段无效时,我希望软键盘保持打开状态.这就是……一个更复杂的地狱.如果有人知道如何实现这样的事情……

  10. android – 如何在Flutter中添加Webview?

    我知道可以将WebView添加为整页,但找不到任何示例代码.我假设你可以使用PageView作为它的基础,但不知道如何调用本机androidWebView并将其添加到PageView.谁能指出我正确的方向?

随机推荐

  1. Flutter 网络请求框架封装详解

    这篇文章主要介绍了Flutter 网络请求框架封装详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  2. Android单选按钮RadioButton的使用详解

    今天小编就为大家分享一篇关于Android单选按钮RadioButton的使用详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

  3. 解决android studio 打包发现generate signed apk 消失不见问题

    这篇文章主要介绍了解决android studio 打包发现generate signed apk 消失不见问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

  4. Android 实现自定义圆形listview功能的实例代码

    这篇文章主要介绍了Android 实现自定义圆形listview功能的实例代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  5. 详解Android studio 动态fragment的用法

    这篇文章主要介绍了Android studio 动态fragment的用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  6. Android用RecyclerView实现图标拖拽排序以及增删管理

    这篇文章主要介绍了Android用RecyclerView实现图标拖拽排序以及增删管理的方法,帮助大家更好的理解和学习使用Android,感兴趣的朋友可以了解下

  7. Android notifyDataSetChanged() 动态更新ListView案例详解

    这篇文章主要介绍了Android notifyDataSetChanged() 动态更新ListView案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下

  8. Android自定义View实现弹幕效果

    这篇文章主要为大家详细介绍了Android自定义View实现弹幕效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  9. Android自定义View实现跟随手指移动

    这篇文章主要为大家详细介绍了Android自定义View实现跟随手指移动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. Android实现多点触摸操作

    这篇文章主要介绍了Android实现多点触摸操作,实现图片的放大、缩小和旋转等处理,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部