Flutter:将可扩展文本字段与BottomNavigationBar一起使用 [英] Flutter: Using Expandable Textfield with BottomNavigationBar

查看:105
本文介绍了Flutter:将可扩展文本字段与BottomNavigationBar一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要这种布局的帮助:)

I need some help with this layout :)

布局包含BottomNavigationBar.主体由顶部的Container(用作某种标题)和Container下方的Textfield组成. Textfield应该展开以填充剩余的空间.一旦用户输入足够多的行以使文本不能显示在屏幕上,整个主体(TextfieldContainer)应变为scrollable.

The Layout contains a BottomNavigationBar. The body consists of a Container at the top (which serves as some kind of header) and a Textfield below the Container. The Textfield should expand to fill the remaining space. As soon as the user enters enough lines so that the text doesn't fit on the screen, the whole body (Textfield and Container) should become scrollable.

因此,它基本上是一个具有Header(Container部分)和多个Tabs的Note应用程序.

So it's basically a note app with a Header (the Container part) and multiple Tabs for Note taking.

这是到目前为止的解决方案:

This is the solution so far:

  Scaffold buildBody(BuildContext context) {
    return Scaffold(
      appBar: AppBar(...),
      body: _buildScaffoldBody(),
      bottomNavigationBar: Column(
        mainAxisSize: MainAxisSize.min,
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          AnimatedCrossFade(
            firstChild: Material(
              color: Theme.of(context).primaryColor,
              child: TabBar(
                controller: _tabController,
                tabs: _tabNames,
                onTap: (int) {
                 ...
                },
              ),
            ),
            secondChild: Container(),
            crossFadeState: _screen == 0
                            ? CrossFadeState.showFirst
                            : CrossFadeState.showSecond,
            duration: const Duration(milliseconds: 300),
          ),
        ],
      ),
    );
  }

Widget _buildScaffoldBody() {
return LayoutBuilder(
      builder: (context, constraint) {
        return SingleChildScrollView(
          child: ConstrainedBox(
            constraints: BoxConstraints(minHeight: constraint.maxHeight),
            child: IntrinsicHeight(
              child: Column(
                children: <Widget>[
                  Container(
                    height: 100,
                    alignment: Alignment.center,
                    color: Colors.green,
                    child: Text("Header"),
                  ),
                 Expanded(              //This is probably the cause 
                    child:  TabBarView(    //of the exception
                        controller: _tabController,
                        children: <Widget>[
                          TextField(
                            expands: true,
                            maxLines: null,
                            decoration: InputDecoration(
                                fillColor: Colors.blue[200], filled: true),
                          ),
                          TextField(
                            expands: true,
                            maxLines: null,
                            decoration: InputDecoration(
                                fillColor: Colors.blue[200], filled: true),
                          ),
                          TextField(
                            expands: true,
                            maxLines: null,
                            decoration: InputDecoration(
                                fillColor: Colors.blue[200], filled: true),
                          ),
                        ]
                      )
                    )
                ],
              ),
            ),
          ),
        );
      },
    );

但是它引发了异常.我尝试用Container替换Expanded并硬编码heightwidth.如果这样做,则不会引发异常,但是Textfield不再是expandable,并且不会与Header一起滚动.它只在Container内滚动并包裹Textfield.

But it's throwing an exception.I tried replacing Expanded with a Container and hardcoding height and width. If I do so the exception is not thrown, but the Textfield is no longer expandable and it doesn't scroll together with the Header. It only scrolls within the Container wrapping the Textfield.

The following assertion was thrown during performLayout():
I/flutter ( 8080): RenderViewport does not support returning intrinsic dimensions.
I/flutter ( 8080): Calculating the intrinsic dimensions would require instantiating every child of the viewport, which
I/flutter ( 8080): defeats the point of viewports being lazy.
I/flutter ( 8080): If you are merely trying to shrink-wrap the viewport in the main axis direction, consider a
I/flutter ( 8080): RenderShrinkWrappingViewport render object (ShrinkWrappingViewport widget), which achieves that
I/flutter ( 8080): effect without implementing the intrinsic dimension API.
I/flutter ( 8080): 
I/flutter ( 8080): The relevant error-causing widget was:
I/flutter ( 8080):   IntrinsicHeight

推荐答案

您只是放错了一些东西.尽力将代码分解成可重用的小部件.它有助于保持一切井井有条.

You just have some stuff misplaced. Try as much as you can to break apart your code into re-usable widgets. It helps to keep everything more organized.

此外,作为一般规则,当您尝试实现一些常用的东西时,很可能已经为它构建了一个小部件.在这种情况下,您无需弄乱AnimatedCrossFade等...所有内容都内置在TabBarView中.

Also, as a general rule, when you're trying to implement something commonly needed, chances are there will be a widget built for it already. In this case, you don't need to mess with the AnimatedCrossFade etc... It's all built into the TabBarView.

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

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: TabBarScaffold(),
    );
  }
}

class TabBarScaffold extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      color: Colors.yellow,
      home: DefaultTabController(
        length: 3,
        child: new Scaffold(
          body: MyPages(),
          bottomNavigationBar: MyTabs(),
        ),
      ),
    );
  }
}

class MyTabs extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return TabBar(
      tabs: [
        Tab(
          child: Text("Tab 1"),
        ),
        Tab(
          child: Text("Tab 2"),
        ),
        Tab(
          child: Text("Tab 3"),
        ),
      ],
      labelColor: Colors.blue,
      unselectedLabelColor: Colors.black,
      indicatorSize: TabBarIndicatorSize.label,
      indicatorPadding: EdgeInsets.all(5.0),
      indicatorColor: Colors.red,
    );
  }
}

class MyPages extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return TabBarView(
      children: [
        MyPageBody(
          textBackgroundColor: Colors.blue[200],
        ),
        MyPageBody(
          textBackgroundColor: Colors.green[200],
        ),
        MyPageBody(
          textBackgroundColor: Colors.red[200],
        ),
      ],
    );
  }
}

class MyPageBody extends StatelessWidget {
  final Color textBackgroundColor;
  MyPageBody({this.textBackgroundColor});

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraint) {
        return SingleChildScrollView(
          child: ConstrainedBox(
            constraints: BoxConstraints(minHeight: constraint.maxHeight),
            child: IntrinsicHeight(
              child: Column(
                children: <Widget>[
                  Container(
                    height: 100,
                    alignment: Alignment.center,
                    color: Colors.green,
                    child: Text("Header"),
                  ),
                  Expanded(
                    child: TextField(
                      expands: true,
                      maxLines: null,
                      decoration: InputDecoration(
                          fillColor: textBackgroundColor, filled: true),
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      },
    );
  }
}

这篇关于Flutter:将可扩展文本字段与BottomNavigationBar一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆