I have a hero image, consisting of a SliverAppBar with a child of FlexibleSpaceBar containing the hero image.
When the user scrolls down the page the hero image scrolls up fading to white. White is the initial colour of the appbar.
But, as per material3, as the user scrolls the appbar transitions from its initial color to be a brighter, saturated version of the page's background colour.
So for some time I have an envelope of white, which was the hero image, meeting the brightly saturated appbar. This looks shabby.
You can see beneath the Appbar title "Samuel" there is a window of white. This is the hero image having faded out.
How do I modify this to be material 3? I think really that window of white should match the Appbar's colour. How do I do that?
return NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
expandedHeight: (widget.neighbour.picUrl ?? "") != ""
? (MediaQuery.of(context).size.width * 4/3) : 256, //300,
automaticallyImplyLeading: false, // removes back arrow over pic.
flexibleSpace: FlexibleSpaceBar(
background: profilePicWidget,
title: Text(widget.neighbour.firstName ??
widget.neighbour.surname ??
""),
),
),
];
},
body: Theme(
data: Theme.of(context),
child: ListView(children: [
This is the hero image, AKA profilePicWidget
profilePicWidget = FittedBox(
fit: BoxFit.fitWidth,
child: Align(
heightFactor: 1,//0.7,
alignment: Alignment.topCenter,
child: Center(
child: Hero(
tag:
"Loaner${widget.neighbour.firebaseId}",
child: Material(
child: InkWell(
onTap: () => Navigator.pop(context),
child: (widget.neighbour.picUrl != null)
? CachedNetworkImage(
progressIndicatorBuilder: (context, url, downloadProgress) =>
Container(child:
CircularProgressIndicator(value: downloadProgress.progress,
valueColor:
AlwaysStoppedAnimation<Color>(themeColor),),
width: 50.0,
height: 50.0,
padding: EdgeInsets.all(15.0),
),
imageUrl: widget.neighbour.picUrl!,
fit: BoxFit.cover,
errorWidget: (context, url, error) //=>
{
print(LOG + "Failed to load picUrl, error: $error");
return Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 48),
child: Image.asset(
PersonUtils.getAvatarFromId[//if avatar is Ninja, go highRes ninja
widget.neighbour.avatar == 99 ? 100 : widget.neighbour.avatar]!,
width: 256,
));
}
)
: Padding(
padding: EdgeInsets.fromLTRB(0, 0, 0, 16),
child: Image.asset(
PersonUtils.getAvatarFromId[
widget.neighbour.avatar == 99 ? 100 : widget.neighbour.avatar]!,
width: 256,
)),
),
)))));
Add the AppBarSystemChromeController inside your build method before returning the Scaffold. This will adjust the system UI colors according to the AppBar's color. Also, consider wrapping your FittedBox in a Container to control the background color.
AppBarSystemChromeController(
// AppBar's color
brightness: Brightness.light,
backgroundColor: appBarBackgroundColor, // set AppBar's background
// Other AppBar styling properties
statusBarBrightness: Brightness.dark,
statusBarColor: appBarBackgroundColor, //AppBar's background color
systemNavigationBarColor: appBarBackgroundColor, // AppBar's background
systemNavigationBarIconBrightness: Brightness.dark,
child: Scaffold(
body: NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[
SliverAppBar(
// other properties
),
];
},
body: Theme(
// theme
child: ListView(
children: [
// ListView children
Container(
color: appBarBackgroundColor, // set the same color as your AppBar
child: profilePicWidget, // Your hero image widget
),
// other widgets
],
),
),
),
),
),