Flutter Dynamic 最大高度

Flutter Dynamic maxHeight

我按照 https://github.com/flutter/flutter/issues/9365 中的建议构建了一个滚动文本字段。现在我希望 ConstrainedBox 的 maxHeight 根据显示或未显示的键盘动态变化。有办法实现吗?

Widget _buildTextInput() {
 return new Container(
  padding: new EdgeInsets.all(7.0),
  child: new ConstrainedBox(
    constraints: new BoxConstraints(
      maxHeight: 150.0 <-- This should be dynamic
    ),

    child: new SingleChildScrollView(
      scrollDirection: Axis.vertical,
      reverse: true,

      // here's the actual text box
      child: new TextField(
        keyboardType: TextInputType.multiline,
        maxLines: null, //grow automatically
        decoration: new InputDecoration.collapsed(
            hintText: 'Please enter a lot of text',
        ),
      ),
    ),
  ),
 );
}

The red box should be the constrained box with open keyboard.

And like so with a closed keyboard.

编辑: 我正在尝试构建一个类似于 Twitter 上的 posting 的输入字段。我需要组合一个 CircleAvatar、一个 TextField 和一个 GridView 来显示用户的头像、他的 post 和一些图像。就像在 Twitter 上一样,我希望整个内容都可以滚动,而不仅仅是 TextField——无论是在键入时还是在查看用户键入或上传的内容时。此外,(多行)TextField 应该在可见区域中键入时滚动(记住打开或关闭的键盘),以便用户可以看到他正在键入的内容。

即使 Flutter TextField 现在自动滚动,我也无法让整个集群正常工作。任何的想法?

自从我相信 6 月初(2018 年)以来,文本字段小部件就已支持自动滚动 - 我认为 this is the commit 添加了它。您可能需要更新到最新的 flutter 版本才能正常工作,但这包含在版本 5.5 中。

这稍微简化了一些事情 - 这应该是您需要做的所有事情才能让它按您想要的方式工作:

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new MyAppState();
}

class MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("Example"),
        ),
        body: new Container(
          padding: new EdgeInsets.all(7.0),
          child: new TextField(
            keyboardType: TextInputType.multiline,
            maxLines: null,
            decoration: new InputDecoration.collapsed(
              hintText: 'Please enter a lot of text',
            ),
          ),
        ),
      ),
    );
  }
}

编辑:为了回答 OP 的编辑问题 - 希望在与文本视图相同的滚动窗格中包含其他元素,我做了这个:

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new MyAppState();
}

class MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("Example"),
        ),
        body: new SingleChildScrollView(
          child: new Container(
            padding: new EdgeInsets.all(7.0),
            child: new Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                new CircleAvatar(
                  backgroundColor: Colors.blue,
                  child: new Text("AB"),
                ),
                new Expanded(
                  child: new Column(
                    children: [
                      new TextField(
                        keyboardType: TextInputType.multiline,
                        maxLines: null,
                        decoration: new InputDecoration.collapsed(
                          hintText: 'Please enter a lot of text',
                        ),
                      ),
                      new Container(
                        height: 300.0,
                        width: 100.0,
                        color: Colors.green,
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

通过使用 SingleChildScrollView,我们仍然允许 children 设置视口的大小(与必须设置该大小的 MultiChildLayoutDelegate 等相反)。 textview 会根据需要变大,但不会自行滚动,因为它的高度不受限制。行内需要 Expanded 以确保右侧(带有文本和图片)在水平方向尽可能大。