【问题标题】:Expand The App bar in Flutter to Allow Multi-Line Title?展开 Flutter 中的应用栏以允许多行标题?
【发布时间】:2018-11-18 17:54:14
【问题描述】:

有谁知道我如何根据此处显示的材料指南创建具有多行标题的应用栏?

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

任何想法如何做到这一点?鉴于它是材料指南的一部分,它似乎应该很简单!值得指出的是,标题是用户定义的,所以我想让应用栏根据用户输入从单行扩展到多行(可能有限制)。

迈克

【问题讨论】:

    标签: flutter flutter-layout


    【解决方案1】:

    这还没有实现。

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

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

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

    【讨论】:

    • 很遗憾,但感谢您告诉我。还没有实现它似乎很奇怪。有没有办法知道他们是否打算这样做?还是向团队提出请求?
    • 你可以查看他们的 github 并可能引发问题。
    【解决方案2】:

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

    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.deepPurple,
          leading: IconButton(icon: Icon(Icons.menu), onPressed: () {}),
          actions: <Widget>[
            IconButton(icon: Icon(Icons.search), onPressed: () {}),
            IconButton(icon: Icon(Icons.more_vert), onPressed: () {}),
          ],
          bottom: PreferredSize(
            child: Padding(
              padding: const EdgeInsets.fromLTRB(80.0, 0.0, 80.0, 16.0),
              child: Text(
                "Summer Trip to Tokyo and Kyoto",
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 24.0,
                ),
              ),
            ),
            preferredSize: Size(0.0, 80.0),
          ),
        ),
        body: Text("..."),
      );
    }
    

    【讨论】:

    • 我认为你需要说明更多@AyaElsisy :) 你遇到了什么问题?
    【解决方案3】:

    您可以使用富文本:

              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,
          ),
    

    【讨论】:

      【解决方案4】:

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

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

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

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

      【讨论】:

        【解决方案5】:

        试试下面的代码。这将提供多行,您还可以在其中控制文本样式。 如果您不希望所有行都使用不同的样式,请使用 Text 而不是 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
                    ),
        

        【讨论】:

          【解决方案6】:

          这段代码将创建一个自定义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));
            }
          }
          

          【讨论】:

            猜你喜欢
            • 2021-01-23
            • 1970-01-01
            • 2020-06-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-06-29
            相关资源
            最近更新 更多