Expand The App bar in Flutter to Allow Multi-Line Title?

时间:2018-06-08 16:07:42

标签: flutter flutter-layout

Does anyone know how I can create an app bar with a multi-line title, as per the material guidelines show here?

https://material.io/design/components/app-bars-top.html#anatomy

Multi-line app bar

任何想法如何做到这一点?鉴于它是材料指南的一部分,它似乎应该是直截了当的!值得指出标题是用户定义的,所以我想允许应用栏从单行扩展到多行(可能有限制),具体取决于用户输入。

麦克

6 个答案:

答案 0 :(得分:4)

目前尚未实施。

但是,您可以使用为SliverAppBar设计的CustomScrollView来获得类似的结果。

请记住,这不是最佳选择。因为它需要硬编码图标和东西的大小。由于FlexibleSpacebar没有宽度约束。

enter image description here

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter_project/materialSheet.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          SliverMultilineAppBar(
            title: "Summer Trip to Tokyo and Kyoto",
            leading: IconButton(
              onPressed: () {},
              icon: Icon(Icons.menu),
            ),
            actions: <Widget>[
              IconButton(
                onPressed: () {},
                icon: Icon(Icons.search),
              ),
              IconButton(
                onPressed: () {},
                icon: Icon(Icons.more_vert),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

class SliverMultilineAppBar extends StatelessWidget {
  final String title;
  final Widget leading;
  final List<Widget> actions;

  SliverMultilineAppBar({this.title, this.leading, this.actions});

  @override
  Widget build(BuildContext context) {
    final mediaQuery = MediaQuery.of(context);

    double availableWidth = mediaQuery.size.width - 160;
    if (actions != null) {
      availableWidth -= 32 * actions.length;
    }
    if (leading != null) {
      availableWidth -= 32;
    }
    return SliverAppBar(
      expandedHeight: 120.0,
      forceElevated: true,
      leading: leading,
      actions: actions,
      flexibleSpace: FlexibleSpaceBar(
        title: ConstrainedBox(
          constraints: BoxConstraints(
            maxWidth: availableWidth,
          ),
          child: Text(title, textScaleFactor: .8,),
        ),
      ),
    );
  }
}

答案 1 :(得分:2)

尝试以下代码。这将提供多行,您还可以在其中控制文本样式。 如果您不希望所有行都使用不同的样式,请使用文本而不是RichText。

             AppBar(
                title: RichText(
                  textAlign: TextAlign.center,
                  text: TextSpan(
                      text: "Developer Developer",
                      style: TextStyle(fontSize: 20),
                      children: <TextSpan>[
                        TextSpan(
                          text: '\nTrip List',
                          style: TextStyle(
                            fontSize: 16,
                          ),
                        ),
                      ]
                  ),
                ),
                backgroundColor: MissionGPSTheme.themeBlueColor
            ),

enter image description here

答案 2 :(得分:2)

这段代码将创建带有Scaffold的自定义AppBar,该自定义import 'package:flutter/material.dart'; class TwoLinesAppBarScaffold extends StatelessWidget { final Widget body; final String title; final String subtitle; TwoLinesAppBarScaffold({this.body, this.title = "QuitNow!", this.subtitle}); @override Widget build(BuildContext context) { Widget widget; if (subtitle == null) { widget = Text(title); } else { widget = RichText( textAlign: TextAlign.start, text: TextSpan( text: title, style: TextStyle( fontSize: 20, fontWeight: FontWeight.w500, ), children: <TextSpan>[ TextSpan( text: '\n$subtitle', style: TextStyle( fontSize: 16, fontWeight: FontWeight.normal, ), ), ]), ); } return Scaffold( appBar: AppBar( title: widget, ), body: Center(child: body)); } } 支持不接收标题,标题以及标题和副标题。如果您不提供标题,它将显示给定的文本(在示例中为应用程序的名称),而如果您设置标题和副标题,它将使用带有适当材质的两行样式设计文字样式。

An AppBar with one line and two lines

# Currently this is rolled into one module, split it if
# we ever create a separate SPI interface for MPU-3050
obj-$(CONFIG_MPU3050) += mpu3050.o
mpu3050-objs := mpu3050-core.o mpu3050-i2c.o

答案 3 :(得分:1)

AppBar将使您接近这一点,但是您必须根据文本长度指示底部PreferredSize小部件的高度,这并不理想。

”在此处输入图片描述“

  @override
小部件build(BuildContext context){
  返回脚手架(
    appBar:AppBar(
      backgroundColor:Colors.deepPurple,
      前导:IconButton(图标:Icon(Icons.menu),onPressed :(){}),
      动作: [
        IconButton(icon:Icon(Icons.search),onPressed:(){}),
        IconButton(icon:Icon(Icons.more_vert),onPressed:(){}),
      ],
      底部:PreferredSize(
        孩子:填充(
          填充:const EdgeInsets.fromLTRB(80.0,0.0,80.0,16.0),
          子代:文字(
            “东京和京都的夏季旅行”,
            样式:TextStyle(
              颜色:Colors.white,
              fontSize:24.0,
            ),
          ),
        ),
        preferredSize:Size(0.0,80.0),
      ),
    ),
    正文(”...”),
  );
}
 

答案 4 :(得分:0)

您可以使用RichText:

          SliverAppBar(
        flexibleSpace: FlexibleSpaceBar(
          background: Container(
            color: Colors.indigoAccent,
          ),
          title: RichText(
            text: TextSpan(children: [
              TextSpan(
                text: Constants.homePageTitle,
                style: textTheme.headline,
              ),
              TextSpan(text: "\n"),
              TextSpan(
                text: Constants.homePageSubtitle,
                style: textTheme.subtitle,
              )
            ]),
          ),
          titlePadding: EdgeInsets.only(left: 10, bottom: 20),
        ),
        floating: true,
        backgroundColor: Colors.greenAccent,
        expandedHeight: 150.0,
      ),

答案 5 :(得分:0)

这可以通过将AppBar的“ title”属性替换为“ flexibleSpace”来实现:

  Scaffold(
    appBar: AppBar(
      flexibleSpace: Center(
        child: Column(
          children: [
            Text('Title Line One'),
            Text('Title Line Two'),
          ],
        ),
      ),
    ),
    body: body
  ),

如果由于高度而发生溢出,只需将AppBar用PreferredSize小部件包装,然后将高度设置为比默认值高的值:

  Scaffold(
    appBar: PreferredSize(
      preferredSize: Size.fromHeight(100),
      child: AppBar(...),
    ),
  ),