如何基于Flutter中的AppBar内容在运行时动态更改AppBar的高度?

时间:2020-01-30 21:43:01

标签: flutter autoresize flutter-appbar

我正在尝试在AppBar内实现flutter_tagging。我设法在TextField内添加了标记的AppBar,并使用AppBar小部件使用以下代码来调整PreferredSize的大小:

return PreferredSize(
    preferredSize: Size.fromHeight(110),
    child: AppBar(
      backgroundColor: HexColor('171551'),
      leading: const BackButton(),
      flexibleSpace: Padding(
        padding: const EdgeInsets.only(top: 48.0, left: 10, right: 10),
        child: buildTaggedSearch(),
      ),
      title: Container(),
      actions: _buildActions(),
    ),
  );

这是结果:

enter image description here

我无法解决的问题是,当用户输入太多标签并且标签进入第二行时,会发生什么情况?

enter image description here

我还是太新了,可能会错过一些东西,但是我该如何解决这个问题,并根据标签的内容调整AppBar的大小。我在这里讨论了有关AppBar调整大小的大多数问题,全部使用了我在这里使用的PreferredSize小部件。所以我想知道是否还有其他选择?

2 个答案:

答案 0 :(得分:3)

没有一种简单的方法可以在运行时更改AppBar的高度。是的,您可以使用PreferredSize将其设置为任何(固定)高度,但是一旦设置,通常就无法更改。

即使您自己创建了扩展PreferredSize的类,它也会最终如下所示:

class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
  @override
  Size get preferredSize => Size.fromHeight(100); // fixed custom height

  @override
  Widget build(BuildContext context) {...}
}

preferredSize获取器需要返回固定大小。它的父窗口小部件(Scaffold)确实想知道应用栏的高度,因此它知道从何处开始渲染其主体。

如果将上述“ CustomAppBar”更改为Stateful,您将很快意识到必须覆盖的preferredSize是窗口小部件的一部分,而不是状态的一部分。

如果您进行某种形式的修改,例如使用全局变量“欺骗”它:

Size get preferredSize => Size.fromHeight(myAppBarHeight); // global variable

更改myAppBarHeight中的值后,应用程序栏仍保持其旧高度。您必须使用setState在小部件上调用Scaffold才能重新绘制应用程序栏,更重要的是,要在其他位置重新绘制脚手架主体。

实际上,解决方案也许是,以便将应用栏的高度控制在Scaffold级别。

或者也许您应该研究SliverAppBar

或者不要尝试在运行时更改应用栏的高度,例如,使用ListView来水平滚动筹码。

或者构建自己的窗口小部件,而不使用应用程序栏。

答案 1 :(得分:0)

我遇到了同样的问题,我想与过滤器一起显示搜索,过滤器不是带有正文内容的滚动,即它固定在顶部并且结果是可滚动的。

而不是使用 AppBar 我做了以下,

Scaffold(
  body: Column(
    children: [
      _buildSearchHeader(),
      Expanded(
        child: ListView(
          children: [
              _buildSearchProductResult()
          ],
        ),
      ),
    ],
  )

_buildSearchHeader() 中,我声明了我的应用栏内容。

SafeArea(
  child: Container(
    margin: EdgeInsets.fromLTRB(
        homePageMargin, homePageMargin, homePageMargin, 0),
    width: double.infinity,
    child: Column(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: [
        Align(child: SectionTitle("Search", fontSize: 20),
            alignment: Alignment.centerLeft),
        SizedBox(height: 22),
        _buildSearchBox(), // search bar
        if(showSortSection) _buildSortSection() // sort section/ or any other 
      ],
    ),
  ),
);

现在我可以完美地创建动态显示和滚动选项。

注意:这可能不是完美的方法。如果任何开发人员知道更好的方法,请在此处告诉我。