Home > front end >  Flutter sliver title from center to left when collapsing
Flutter sliver title from center to left when collapsing

Time:04-23

My goal is to follow what I designed (inspired by Samsung weather) but implementing the code is difficult when you're just starting to learn. When expanded the title should be centered and when collapsed will stay in the upper left.

enter image description here

So far this is my code and my current progress. The tricky part is to move the title to the center.

      Scaffold(
        backgroundColor: Colors.transparent,
        body: CustomScrollView(
          slivers: [
            SliverAppBar(
              actions: <Widget>[
                IconButton(
                  icon: const Icon(Icons.search),
                  onPressed: () {},
                ),
              ],
              pinned: _pinned,
              snap: _snap,
              floating: _floating,
              expandedHeight: 160,
              backgroundColor: Colors.transparent,
              elevation: 0.0,
              flexibleSpace: FlexibleSpaceBar(
                titlePadding: EdgeInsets.all(18),
                // centerTitle: true,
                title: Text('Panahon'),
              ),
            ),
            SliverToBoxAdapter(
                child: SizedBox(
              height: 800,
              child: Card(),
            ))
          ],
        ),
      ),

enter image description here

enter image description here

edit: The app dynamically changes themes dependent on the time.

CodePudding user response:

You can create custom sliver app bar by using SliverPersistentHeaderDelegate, you will get shrinkOffset that can be used to animate app bar elements.

Run on dartPad

Replace your SliverAppBar with this

SliverPersistentHeader(
  pinned: true,
  delegate: MySliverHeaderDelegate(onActionTap: () {
    debugPrint("on Tap");
  }),
),

And custom SliverHeaderDelegate

class MySliverHeaderDelegate extends SliverPersistentHeaderDelegate {
  final double _maxExtent = 160;
  final VoidCallback onActionTap;

  MySliverHeaderDelegate({
    required this.onActionTap,
  });
  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    debugPrint(shrinkOffset.toString());
    return Container(
      color: Colors.cyanAccent,
      child: Stack(
        children: [
          Align(
            alignment: Alignment(
                //little padding
                -(shrinkOffset > _maxExtent - 20
                        ? _maxExtent - 20
                        : shrinkOffset) /
                    _maxExtent,
                0),
            child: const Text('Panahon'),
          ),

          // here provide actions
          Positioned(
            top: 0,
            right: 0,
            child: IconButton(
              icon: const Icon(Icons.search),
              onPressed: onActionTap,
            ),
          ),
        ],
      ),
    );
  }

  @override
  double get maxExtent => _maxExtent;

  @override
  double get minExtent => kToolbarHeight;

  @override
  bool shouldRebuild(covariant MySliverHeaderDelegate oldDelegate) {
    return oldDelegate != this;
  }
}
  • Related