简体   繁体   English

Flutter:在BottomNavigationBar 中使用可扩展文本字段

[英]Flutter: Using Expandable Textfield with BottomNavigationBar

I need some help with this layout :)我需要一些有关此布局的帮助:)

The Layout contains a BottomNavigationBar .布局包含一个BottomNavigationBar The body consists of a Container at the top (which serves as some kind of header) and a Textfield below the Container .主体由顶部的Container (用作某种标题)和Container下方的Textfield The Textfield should expand to fill the remaining space. Textfield应扩展以填充剩余空间。 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 .一旦用户输入了足够多的行以致文本无法显示在屏幕上,整个正文( TextfieldContainer )应该变为scrollable

So it's basically a note app with a Header (the Container part) and multiple Tabs for Note taking.所以它基本上是一个带有HeaderContainer部分)和多个用于记笔记的Tabs的笔记应用程序。

在此处输入图片说明

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),
                          ),
                        ]
                      )
                    )
                ],
              ),
            ),
          ),
        );
      },
    );

But it's throwing an exception.I tried replacing Expanded with a Container and hardcoding height and width .但它抛出了一个异常。我尝试用Container替换Expanded并硬编码heightwidth 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 .如果我这样做,则不会抛出异常,但Textfield不再expandable ,并且不会与Header一起滚动。 It only scrolls within the Container wrapping the Textfield .它仅在包装TextfieldContainer内滚动。

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.它有助于让一切更有条理。

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 .在这种情况下,您不需要弄乱AnimatedCrossFade等......它都内置在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),
                    ),
                  ),
                ],
              ),
            ),
          ),
        );
      },
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM