未检测到键盘。 MediaQuery.of(context).viewInsets.bottom 始终返回 0.0

问题描述 投票:0回答:9

我有一个支架,里面有一个 TextField。当键盘之前将该字段移动到键盘上方时,键盘始终会覆盖该字段。我项目中的所有页面都发生这种情况。

我已将 MediaQuery.of(context).viewInsets.bottom 添加到我的构建方法中,它始终返回 0.0。当键盘出现时,没有重建。我尝试将 resizeToAvoidBottomInset 设置为 true 和 false,没有任何更改。我尝试将其包装在可滚动小部件中,没有任何变化。

在 IOS 中一切正常,这只影响 Android 构建。

Doctor summary (to see all details, run flutter doctor -v):  
[✓] Flutter (Channel unknown, v1.10.15, on Mac OS X 10.15.1 19B88, locale en-US)  

[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)  
[✓] Xcode - develop for iOS and macOS (Xcode 11.2.1)  
[✓] Android Studio  
[✓] Android Studio (version 3.5)  
[✓] VS Code (version 1.40.2)  
[✓] Connected device (1 available)
android flutter dart flutter-layout
9个回答
10
投票

我最近遇到了这个问题。您是否将全屏设置为true?如果启用全屏,MediaQuery.viewInsets.bottom 将返回 0.0。由于您提到该问题仅发生在 android 中,因此您可能在本机 android 文件中设置了全屏属性。检查样式.xml

    <item name="android:windowFullscreen">false</item>

从应用程序中删除全屏的其他方法是在 flutter 页面中

SystemChrome.setEnabledSystemUIOverlays([])

您可能还想检查的另一件事是 Scaffold 中的

resizeToAvoidBottomPadding:
为 false。

Flutter issues 中也提出了该问题:https://github.com/flutter/flutter/issues/25050


8
投票

我找到了这个问题的原因,但不知道为什么。当控件在Scaffold中时,键盘的出现和消失不会在Scaffold中重建body。可以尝试用Material替换Scaffold来观察。如果你不想更换 Scaffold,我能找到的一种方法是:

final bottom= EdgeInsets.fromWindowPadding(
    WidgetsBinding.instance.window.viewInsets,
    WidgetsBinding.instance.window.devicePixelRatio).bottom;

4
投票

查看您是否已将

useInheritedMediaQuery
中的
true
设置为
MaterialApp
。如果是这样,请将其设置为
false
。 这是因为该属性强制小部件使用继承的上下文。因此,例如,如果您在应用程序启动时立即弹出键盘,则
MediaQuery.of(context).viewInsets.bottom
的值与键盘的大小相同,但由于该上下文现在适用于儿童,因此即使键盘折叠,它也永远不会改变。 因此,当我遇到这个问题时,我的简单解决方案是将
useInheritedMediaQuery
设置为
false
,这是当今 Flutter 应用程序中的默认设置。


0
投票

在复杂的小部件树的情况下,即使键盘打开,MediaQuery.of(context).viewInsets.bottom 也会给出 null。所以,我们必须改变树上的值。

这个包提供了简单易用的提供程序,用于从树上获取信息https://pub.dev/packages/flutter_keyboard_size

或者,您可以自己在树中更改有关键盘大小的信息(您可以查看包中的代码)。


0
投票

当键盘打开时,MediaQuery.of(context).viewInsets.bottom 会发生变化以反映新的底部(现在位于键盘的顶部)。

但是,Android 应用程序可能处于全屏状态:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
        <!-- Show a splash screen on the activity. Automatically removed when
             Flutter draws its first frame -->
        <item name="android:windowBackground">@drawable/launch_background</item>
        <item name="android:windowFullscreen">true</item>
    </style>
    <color name="xxx">#FFFF00</color>
</resources>

在这种情况下,

viewInsets.bottom
将始终是
0.0
,即使键盘打开时,


0
投票

为托管 Flutter 屏幕的 Activity 设置

android:windowSoftInputMode="adjustResize"
in AndroidManifest.xml
将解决该问题。


0
投票

我需要混合flutter和Android,情况可能会更复杂,

<item name="android:windowFullscreen">false</item>
SystemChrome.setEnabledSystemUIOverlays([])
不适合我。

最后

android:windowSoftInputMode="adjustResize"
中的设置
AndroidManifest.xml
对我有用。


0
投票

尝试 MediaQuery.of(context).viewInsets.bottom 与脚手架上下文而不是子小部件之一。

它对我有用。


0
投票

我还没有看到我的解决方案,所以将其发布在这里。

听起来令人惊讶,我使用了以下代码:

final keyboardHeight = MediaQuery.of(Scaffold.of(context).context).viewInsets.bottom;

解决方案来自github上的这条评论

就我而言,我使用的是第一个示例 SingleChildScrollView

Row
而不是
Column

一旦选择了

Column
Row
内的每个
TextField
都没有正确的高度,所以我需要在
constraints.maxHeight + keyboardHeight
内执行
LayoutBuilder
以获得正确的高度,无论是键盘是否显示。

© www.soinside.com 2019 - 2024. All rights reserved.