skip to Main Content

enter image description here

Since i am new to flutter i want the complete implementation of this animation.

2

Answers


  1. /// Flutter code sample for SliverAppBar
    
    // This sample shows a [SliverAppBar] and it's behavior when using the
    // [pinned], [snap] and [floating] parameters.
    
    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    /// This is the main application widget.
    class MyApp extends StatelessWidget {
      static const String _title = 'Flutter Code Sample';
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          title: _title,
          home: MyStatefulWidget(),
        );
      }
    }
    
    /// This is the stateful widget that the main application instantiates.
    class MyStatefulWidget extends StatefulWidget {
      const MyStatefulWidget();
    
      @override
      _MyStatefulWidgetState createState() => _MyStatefulWidgetState();
    }
    
    /// This is the private State class that goes with MyStatefulWidget.
    class _MyStatefulWidgetState extends State<MyStatefulWidget> {
      bool _pinned = true;
      bool _snap = false;
      bool _floating = false;
    
    // [SliverAppBar]s are typically used in [CustomScrollView.slivers], which in
    // turn can be placed in a [Scaffold.body].
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: CustomScrollView(
            slivers: <Widget>[
              SliverAppBar(
                pinned: _pinned,
                snap: _snap,
                floating: _floating,
                expandedHeight: 160.0,
                flexibleSpace: const FlexibleSpaceBar(
                  title: Text('SliverAppBar'),
                  background: FlutterLogo(),
                ),
              ),
              const SliverToBoxAdapter(
                child: SizedBox(
                  height: 20,
                  child: Center(
                    child: Text('Scroll to see the SliverAppBar in effect.'),
                  ),
                ),
              ),
              SliverList(
                delegate: SliverChildBuilderDelegate(
                  (BuildContext context, int index) {
                    return Container(
                      color: index.isOdd ? Colors.white : Colors.black12,
                      height: 100.0,
                      child: Center(
                        child: Text('$index', textScaleFactor: 5),
                      ),
                    );
                  },
                  childCount: 20,
                ),
              ),
            ],
          ),
          bottomNavigationBar: BottomAppBar(
            child: ButtonBar(
              alignment: MainAxisAlignment.spaceEvenly,
              children: <Widget>[
                Row(
                  children: <Widget>[
                    const Text('pinned'),
                    Switch(
                      onChanged: (bool val) {
                        setState(() {
                          _pinned = val;
                        });
                      },
                      value: _pinned,
                    ),
                  ],
                ),
                Row(
                  children: <Widget>[
                    const Text('snap'),
                    Switch(
                      onChanged: (bool val) {
                        setState(() {
                          _snap = val;
                          // Snapping only applies when the app bar is floating.
                          _floating = _floating || _snap;
                        });
                      },
                      value: _snap,
                    ),
                  ],
                ),
                Row(
                  children: <Widget>[
                    const Text('floating'),
                    Switch(
                      onChanged: (bool val) {
                        setState(() {
                          _floating = val;
                          _snap = _snap && _floating;
                        });
                      },
                      value: _floating,
                    ),
                  ],
                ),
              ],
            ),
          ),
        );
      }
    }
    

    Source – https://api.flutter.dev/flutter/material/SliverAppBar-class.html

    Login or Signup to reply.
  2. This is exact implementation of this AppBar:

    class TransitionAppBar extends StatelessWidget {
      TransitionAppBar({
        required this.avatar,
        required this.title,
        this.extent = 250,
        Key? key,
      }) : super(key: key);
    
      final Widget avatar;
      final double extent;
      final String title;
    
      @override
      Widget build(BuildContext context) {
        return SliverPersistentHeader(
          pinned: true,
          delegate: _TransitionAppBarDelegate(
            avatar: avatar,
            title: title,
            extent: extent > 200 ? extent : 200,
          ),
        );
      }
    }
    
    class _TransitionAppBarDelegate extends SliverPersistentHeaderDelegate {
      _TransitionAppBarDelegate({required this.avatar, required this.title, this.extent = 250})
          : assert(extent >= 200, '');
    
      final Widget avatar;
      final double extent;
      final String title;
    
      final _avatarAlignTween = AlignmentTween(begin: Alignment.bottomCenter, end: Alignment.topLeft);
      final _avatarMarginTween = EdgeInsetsTween(
        end: EdgeInsets.only(left: 14, top: 36),
      );
    
      final _iconAlignTween = AlignmentTween(begin: Alignment.bottomRight, end: Alignment.topRight);
      final _titleMarginTween = EdgeInsetsTween(
        begin: EdgeInsets.only(bottom: 20),
        end: EdgeInsets.only(left: 64, top: 45),
      );
    
      @override
      double get maxExtent => extent;
    
      @override
      double get minExtent => 80;
    
      @override
      bool shouldRebuild(_TransitionAppBarDelegate oldDelegate) {
        return avatar != oldDelegate.avatar || title != oldDelegate.title;
      }
    
      @override
      Widget build(
        BuildContext context,
        double shrinkOffset,
        bool overlapsContent,
      ) {
        final tempVal = maxExtent * 72 / 100;
        final progress = shrinkOffset > tempVal ? 1.0 : shrinkOffset / tempVal;
        final avatarMargin = _avatarMarginTween.lerp(progress);
        final titleMargin = _titleMarginTween.lerp(progress);
    
        final avatarAlign = _avatarAlignTween.lerp(progress);
        final iconAlign = _iconAlignTween.lerp(progress);
    
        final avatarSize = (1 - progress) * 200 + 32;
    
        return Stack(
          children: <Widget>[
            AnimatedContainer(
              duration: Duration(milliseconds: 100),
              height: 80,
              constraints: BoxConstraints(maxHeight: minExtent),
              color: Colors.white,
            ),
            Padding(
              padding: avatarMargin,
              child: Align(
                alignment: avatarAlign,
                child: SizedBox(
                  height: avatarSize,
                  width: avatarSize,
                  child: avatar,
                ),
              ),
            ),
            Align(
              alignment: Alignment.bottomRight,
              child: Container(
                height: progress < 0.4 ? 100 * (1 - progress) * 1.5 : 0,
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    begin: Alignment.topCenter,
                    end: Alignment.bottomCenter,
                    colors: [
                      Colors.pink[200]!.withOpacity(0.05),
                      Colors.pink[400]!.withOpacity(0.8),
                    ],
                  ),
                ),
              ),
            ),
            Padding(
              padding: titleMargin,
              child: Align(
                alignment: avatarAlign,
                child: Text(
                  title,
                ),
              ),
            ),
            Padding(
              padding: titleMargin,
              child: Align(
                alignment: iconAlign,
                child: Padding(
                  padding: const EdgeInsets.only(right: 16),
                  child: GestureDetector(
                    onTap: () {},
                    child: Icon(
                      Icons.search,
                      size: 30,
                      color: progress < 0.4 ? Colors.white : Colors.black,
                    ),
                  ),
                ),
              ),
            ),
          ],
        );
      }
    }
    

    Also this answer might be helpful

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search