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
Any ideas how to do this? It seems like it should be straightforward given that it's part of the material guidelines! Worth pointing out that the title is user defined, so I want to allow the app bar to expand from a single line to multiple lines (perhaps with a limit imposed) depending on user input.
Mike
To make the title in the center of an appbar, use centerTitle:true property in the appbar widget.
In Flutter, if you need to design single line with multiple styles then it can be done by using RichText widget with TextSpan . RichText widget displays text with different styles. Different text to display is represented using a tree of TextSpan widgts.
This is not implemented yet.
However you can achieve similar results by using SliverAppBar
designed for CustomScrollView
.
Bear in mind that this is not optimal though. As it required hard coding the size of the icons and stuff. Due to FlexibleSpacebar
not having width constraint.
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,),
),
),
);
}
}
You can use 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,
),
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With