Flutter: Change text when FlexibleSpaceBar is collapsed

Jakes picture Jakes · Jun 18, 2018 · Viewed 11.6k times · Source

I have looked through the Flutter documentation to try and find an event, callback or even a state that I could hook into when the FlexibleSpaceBar is collapsed or expanded.

return new FlexibleSpaceBar(
  title: new Column(
    crossAxisAlignment: CrossAxisAlignment.end,
    mainAxisAlignment: MainAxisAlignment.end,
    children: <Widget>[
        new Text(_name, style: textTheme.headline),
        new Text(_caption, style: textTheme.caption)
    ]),
  centerTitle: false,
  background: getImage());`

When the FlexibleSpaceBar is snapped in (collapsed), I want to hide the _caption text and only display the _name text. When it is expanded fully, I obviously want to display both _name & _caption.

How do I go about doing that?

Im new to flutter, so I am somewhat lost on this.

Also reported at https://github.com/flutter/flutter/issues/18567

Answer

elhoucine ayoub picture elhoucine ayoub · Dec 7, 2019

It can be done like this :

inside your initState method add the scroll listener like that :

  ScrollController _controller;
  bool silverCollapsed = false;
  String myTitle = "default title";

  @override
  void initState() {
    super.initState();

    _controller = ScrollController();

    _controller.addListener(() {
       if (_controller.offset > 220 && !_controller.position.outOfRange) {
          if(!silverCollapsed){

            // do what ever you want when silver is collapsing !

            myTitle = "silver collapsed !";
            silverCollapsed = true;
            setState(() {});
          }
       }
       if (_controller.offset <= 220 && !_controller.position.outOfRange) {
         if(silverCollapsed){

            // do what ever you want when silver is expanding !

            myTitle = "silver expanded !";
            silverCollapsed = false;
            setState(() {});
         }
       }
    });
 }

then wrap your silverAppBar inside CustomScrollView and add the controller to this CustomScrollView like that :

 @override
 Widget build(BuildContext context) {
    return Scaffold(
       backgroundColor: Colors.white,
       body: CustomScrollView(
          controller: _controller,
          slivers: <Widget>[
             SliverAppBar(
                expandedHeight: 300,
                title: myTitle,
                flexibleSpace: FlexibleSpaceBar(),
             ),
             SliverList(
                delegate: SliverChildListDelegate(<Widget>[
                   // your widgets inside here !
                ]),
             ),
          ],
       ),
    );
}

finally change the condition value _controller.offset > 220 to fit your need !