Reputation: 1563
Instead of using FlexibleSpaceBar in the flexibleSpace property of SliverAppBar I want to use a custom widget tree, when expanded, but upon scrolling, I want to display a custom text, and not the widget tree.
I have created a custom widget tree which shall be assigned to the flexibleSpace property, but I don't know how to display custom text on scrolling, and hide the widget tree.
SliverAppBar(
expandedHeight: 180.0,
backgroundColor: const Color(0xFF9e0118),
iconTheme: IconThemeData(color: Colors.white),
floating: true,
pinned: true,
flexibleSpace: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 16.0),
padding: EdgeInsets.only(left: 32.0, right: 32.0),
child: Text(
'Some text',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontFamily: 'PlayfairDisplay',
fontStyle: FontStyle.italic,
fontSize: 16.0),
)),
Container(
margin: EdgeInsets.only(top: 16.0),
padding: EdgeInsets.only(left: 32.0, right: 32.0),
child: Text(
'some text',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontFamily: 'PlayfairDisplay',
fontSize: 16.0),
)),
],
),
),
Upvotes: 9
Views: 28656
Reputation: 702
To complete @westdabestdb answer, to make the title appear on scroll, it's really simple.
You just need to add the Animated Widget of you your choice and use the addListener from your scroll controller to switch a boolean. To find more Animated Widgets go to the official docs for Flutter Animated Widgets: https://flutter.dev/docs/development/ui/widgets/animation
Here is an example with an AnimatedOpacity Widget and the Parallax collapse mode which in my opinion work pretty well together.
class YourPage extends StatelessWidget {
const YourPage({Key key}) : super(key: key);
ScrollController _scrollController;
bool _isScrolled = false;
@override
void initState() {
_scrollController = ScrollController();
_scrollController.addListener(_listenToScrollChange);
super.initState();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: CustomScrollView(
controller: _scrollController,
slivers: <Widget>[
SliverAppBar(
expandedHeight: 144.0,
pinned: true,
forceElevated: true,
////////////////////////////////////
// HERE IS THE PART TO BE ADDED
title: AnimatedOpacity(
duration: Duration(milliseconds: 300),
opacity: _isScrolled ? 1.0 : 0.0,
curve: Curves.ease,
child: Text("YOUR TITLE HERE"),
),
////////////////////////////////////
flexibleSpace: FlexibleSpaceBar(
titlePadding: const EdgeInsets.only(bottom: 8.0),
centerTitle: true,
collapseMode: CollapseMode.parallax,
background: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 16.0),
padding: EdgeInsets.only(left: 32.0, right: 32.0),
child: Text(
'Some text',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontFamily: 'PlayfairDisplay',
fontStyle: FontStyle.italic,
fontSize: 16.0),
)),
Container(
margin: EdgeInsets.only(top: 16.0),
padding: EdgeInsets.only(left: 32.0, right: 32.0),
child: Text(
'some text',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontFamily: 'PlayfairDisplay',
fontSize: 16.0),
)),
],
),
),
)
],
),
),
);
}
// METHODS
void _listenToScrollChange() {
if (_scrollController.offset >= 48.0) {
setState(() {
_isScrolled = true;
});
} else {
setState(() {
_isScrolled = false;
});
}
}
}
You will just have to play around with the values of the if in the _listenToScrollChange and the Duration of the animation to obtain the desired output.
Upvotes: 6
Reputation: 4638
You may want to wrap your widget tree inside a FlexibleSpaceBar
widget and add your widget tree as background. I hope I understood your question right. Check this gif.
SliverAppBar(
expandedHeight: 180.0,
backgroundColor: const Color(0xFF9e0118),
iconTheme: IconThemeData(color: Colors.white),
floating: true,
pinned: true,
flexibleSpace: FlexibleSpaceBar(
collapseMode: CollapseMode.pin,
centerTitle: true,
background: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.only(top: 16.0),
padding: EdgeInsets.only(left: 32.0, right: 32.0),
child: Text(
'Some text',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontFamily: 'PlayfairDisplay',
fontStyle: FontStyle.italic,
fontSize: 16.0),
)),
Container(
margin: EdgeInsets.only(top: 16.0),
padding: EdgeInsets.only(left: 32.0, right: 32.0),
child: Text(
'some text',
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontFamily: 'PlayfairDisplay',
fontSize: 16.0),
)),
],
),
),
),
Upvotes: 15