我有一个支架,里面有一个 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)
我最近遇到了这个问题。您是否将全屏设置为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
我找到了这个问题的原因,但不知道为什么。当控件在Scaffold中时,键盘的出现和消失不会在Scaffold中重建body。可以尝试用Material替换Scaffold来观察。如果你不想更换 Scaffold,我能找到的一种方法是:
final bottom= EdgeInsets.fromWindowPadding(
WidgetsBinding.instance.window.viewInsets,
WidgetsBinding.instance.window.devicePixelRatio).bottom;
查看您是否已将
useInheritedMediaQuery
中的 true
设置为 MaterialApp
。如果是这样,请将其设置为 false
。
这是因为该属性强制小部件使用继承的上下文。因此,例如,如果您在应用程序启动时立即弹出键盘,则 MediaQuery.of(context).viewInsets.bottom
的值与键盘的大小相同,但由于该上下文现在适用于儿童,因此即使键盘折叠,它也永远不会改变。
因此,当我遇到这个问题时,我的简单解决方案是将 useInheritedMediaQuery
设置为 false
,这是当今 Flutter 应用程序中的默认设置。
在复杂的小部件树的情况下,即使键盘打开,MediaQuery.of(context).viewInsets.bottom 也会给出 null。所以,我们必须改变树上的值。
这个包提供了简单易用的提供程序,用于从树上获取信息https://pub.dev/packages/flutter_keyboard_size
或者,您可以自己在树中更改有关键盘大小的信息(您可以查看包中的代码)。
当键盘打开时,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
,即使键盘打开时,
为托管 Flutter 屏幕的 Activity 设置
android:windowSoftInputMode="adjustResize"
in AndroidManifest.xml
将解决该问题。
我需要混合flutter和Android,情况可能会更复杂,
<item name="android:windowFullscreen">false</item>
和SystemChrome.setEnabledSystemUIOverlays([])
不适合我。
最后
android:windowSoftInputMode="adjustResize"
中的设置AndroidManifest.xml
对我有用。
尝试 MediaQuery.of(context).viewInsets.bottom 与脚手架上下文而不是子小部件之一。
它对我有用。
我还没有看到我的解决方案,所以将其发布在这里。
听起来令人惊讶,我使用了以下代码:
final keyboardHeight = MediaQuery.of(Scaffold.of(context).context).viewInsets.bottom;
解决方案来自github上的这条评论。
就我而言,我使用的是第一个示例 SingleChildScrollView 和
Row
而不是 Column
。
一旦选择了
Column
,Row
内的每个TextField
都没有正确的高度,所以我需要在constraints.maxHeight + keyboardHeight
内执行LayoutBuilder
以获得正确的高度,无论是键盘是否显示。