键盘出现时,Flutter小部件会调整大小。怎么预防这个?

时间:2017-10-03 18:37:16

标签: keyboard resize widget textfield flutter

我有一个扩展小部件列,如下所示:

 return new Container(
      child: new Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          new Expanded(
            flex: 1,
            child: convertFrom,
          ),
          new Expanded(
            flex: 1,
            child: convertTo,
          ),
          new Expanded(
            flex: 1,
            child: description,
          ),
        ],
      ),
    );

看起来像这样: enter image description here

convertFrom,包含一个TextField。当我点击此文本字段时,Android键盘将出现在屏幕上。这会更改屏幕大小,因此小部件会像这样调整大小: enter image description here

有没有办法让键盘&#34;覆盖&#34;屏幕,以便我的专栏没有调整大小?如果我没有使用Expanded窗口小部件并为每个窗口小部件硬编码,则窗口小部件不会调整大小,但是当键盘出现时我会收到黑黄条纹错误(因为没有& #39;足够的空间)。对于所有屏幕尺寸,这也不灵活。

我不确定这是特定于Android还是特定于Flutter。

13 个答案:

答案 0 :(得分:70)

Scaffold中,将resizeToAvoidBottomPadding属性设为false

答案 1 :(得分:32)

大多数其他答案建议使用resizeToAvoidBottomPadding=false。以我的经验,这可以使键盘掩盖文本字段(如果它们位于出现键盘的位置下方)。

我当前的解决方案是强制将列的高度设置为与屏幕相同,然后将其放置在SingleChildScrollView中,以便Flutter在使用键盘时将屏幕自动向上滚动足够的高度。

Widget build(BuildContext context) {
  return Scaffold(
    body: SingleChildScrollView(
      physics: NeverScrollableScrollPhysics(),
      child: ConstrainedBox(
        constraints: BoxConstraints(
          minWidth: MediaQuery.of(context).size.width,
          minHeight: MediaQuery.of(context).size.height,
        ),
        child: IntrinsicHeight(
          child: Column(
            mainAxisSize: MainAxisSize.max,
            children: <Widget>[
              // CONTENT HERE
            ],
          ),
        ),
      ),
    ),
  );
}

我使用NeverScrollableScrollPhysics,以便用户无法滚动自己。

答案 2 :(得分:4)

好吧,我认为,如果我们实现@Aman的解决方案,它将使我们的应用程序像键盘出现时一样丑陋,它不会根据可用高度调整屏幕的视口,并且会发现其他字段隐藏在键盘后面。因此,我建议改用SingleChildScrollView

按如下所示用SingleChildScrollView包装代码,

 return new Container(
  child: SingleChildScrollView(
    child: new Column(
    crossAxisAlignment: CrossAxisAlignment.stretch,
    children: <Widget>[
      new Expanded(
        flex: 1,
        child: convertFrom,
      ),
      new Expanded(
        flex: 1,
        child: convertTo,
      ),
      new Expanded(
        flex: 1,
        child: description,
      ),
    ],
  ),
 ),
);

答案 3 :(得分:4)

我的方法是将# Example 1 println(generatePrimes(10^7)[end]) # output: empty line # Example 2 println("This first part doesn't print", generatePrimes(10^7)[end]) # output: 9999991 # Example 3 println("This first part doesn't print", generatePrimes(10^7)[end], " prints") # output: 9999991 prints # Example 4 println(generatePrimes(10^7)[end], "prime doesn't print") # output: prime doesn't print println物理一起使用。

SingleChildScrollView

答案 4 :(得分:3)

方法1:从AndroidManifest.xml文件中删除android:windowSoftInputMode="adjustResize"(否则它将覆盖浮动代码),并在Scaffold中添加resizeToAvoidBottomPadding: false,如下所示:

Scaffold(
      resizeToAvoidBottomPadding: false,
      appBar: AppBar()
)

方法2(不推荐):只需在活动中的Android AndroidManifest.xml中添加android:windowSoftInputMode="stateVisible",它将仅适用于Android,不适用于IOS。

<activity
       ...
        android:windowSoftInputMode="stateVisible">

注意:请勿将其设置为android:windowSoftInputMode="adjustResize"

答案 5 :(得分:2)

根据用例,您还可以考虑使用listview。这将确保在没有足够空间时内容滚动。例如,您可以查看图库应用中的textfield演示

答案 6 :(得分:2)

我的建议是,如果键盘突然出现在屏幕上,则无论如何都要使用resizeToAvoidBottomInset: false来防止小部件调整大小。例如,如果用户在您的应用程序中使用Facebook聊天头。

为了防止键盘在需要的屏幕上覆盖小部件,我建议采用以下方法,其中SingleChildScrollView的高度减小为可用空间的高度。在这种情况下,SingleChildScrollView还会滚动到聚焦的窗口小部件。

final double screenHeight = MediaQuery.of(context).size.height;
final double keyboardHeight = MediaQuery.of(context).viewInsets.bottom;
return Scaffold(
  resizeToAvoidBottomInset: false,
  body: SizedBox(
    height: screenHeight - keyboardHeight,
    child: SingleChildScrollView(
      child: Column(
        children: [
          const SizedBox(height: 200),
          for (var i = 0; i < 10; i++) const TextField()
        ],
      ),
    ),
  ),
);

答案 7 :(得分:2)

false 设置值 resizeToAvoidBottomInset 对我来说效果很好。

此外,resizeToAvoidBottomPadding 对我来说效果很好。您可以使用任何一种。

答案 8 :(得分:2)

这是一个完美的解决方案,它使您能够在 SingleChildScrollView 内拥有一个全屏列。这使您可以为所有屏幕尺寸创建完美的布局+具有滚动屏幕的能力,如果您打开键盘或渲染后屏幕溢出(例如文本输入字段验证)

class PerfectFullScreen extends StatelessWidget {
  const PerfectFullScreen({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child: Scaffold(
      backgroundColor: Theme.of(context).backgroundColor,
      appBar: AppBar(),
      body: Builder(
        builder: (context) => SingleChildScrollView(
            child: ConstrainedBox(
                constraints: BoxConstraints(
                    minHeight: MediaQuery.of(context).size.height -
                        (MediaQuery.of(context).padding.top + kToolbarHeight)),
                child: IntrinsicHeight(
                    child: Column(
                  children: [
                    Container(
                      height: randomImageHeight,
                      child: Image.asset(
                        "assets/images/change_password.png",
                        fit: BoxFit.cover,
                      ),
                    ),
                    Expanded(
                        child: WidgetThatShouldTakeRemainingSpace() )
                  ],
                )))),
      ),
    ));
  }
}

重要的部分是 ConstrainedBox 和正确的 BoxConstraintsInstrinsicHeight 小部件。

PS: (MediaQuery.of(context).padding.top + kToolbarHeight) == Appbar 的高度

答案 9 :(得分:1)

对于我来说,将以下项目属性从true更改为false

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

在文件中

android/app/src/main/res/values/styles.xml

使Flutter在输入焦点上将所有页面内容向上拖动

Flutter drag all page content upwards on input focus

答案 10 :(得分:1)

回答可能为时已晚,但以下对我有用

Scaffold(
  body: SingleChildScrollView(
    physics: ClampingScrollPhysics(parent: NeverScrollableScrollPhysics()),
      child: Container(

Clamping 将自动滚动以使文本字段可见,其父 NeverScrollable 将不允许用户滚动。

答案 11 :(得分:0)

resizeToAvoidBottomInset设置为getPhotoUrl而不是已弃用的resizeToAvoidBottomPadding

false

答案 12 :(得分:0)

我遇到了同样的问题,因此我开始尝试随机解决方案来修复它,然后突然修复了它。 enter image description here

将主父容器包装在SingleChildScrollView()中,并为其指定设备高度,即device_height = MediaQuery.of(context).size.height。

这将使整个页面可滚动,但不会调整任何小部件的大小。