szakes1
szakes1

Reputation: 904

How to animate hiding AppBar in Flutter?

I need help with animating my AppBar.

My AppBar hides on DoubleTap, but there's no animation in it, it hides immediately. I want it to be animated. I tried to wrap my AppBar with SlideTransition and AnimatedContainer widget, but none of these work, because the error says I need a PreferredSize widget.

I would be extremely glad, if someone helped me!

I already checked out this answer, but the guy, who answered to this question, has the same problem. There's no animation. Show (slide in) or hide (slide out) flutter AppBar on screen tap

Here's the video of my AppBar: https://streamable.com/it7ib

Here's the photo how my AppBar looks like: flutter

Code:

import 'package:flutter/material.dart';

class GeneratedCouponScreen extends StatefulWidget {
  @override
  _GeneratedCouponScreenState createState() => _GeneratedCouponScreenState();
}

class _GeneratedCouponScreenState extends State<GeneratedCouponScreen> {

  bool showAppBar = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: showAppBar ?  AppBar() : null ,
      backgroundColor: Colors.white,
      body: GestureDetector(
        onDoubleTap: () {
          if (showAppBar) {
            setState(() {
              showAppBar = false;
            });
          } 
          else {
            setState(() {
              showAppBar = true; 
            });
          }
        },
        child: SafeArea(
          child: Container(
            padding: EdgeInsets.all(16.0),
            child: Column(
              children: [
                Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text('DATA WYDANIA:', style: TextStyle(color: Colors.black),),
                      Text('10/09/2019', style: TextStyle(color: Colors.black))
                    ],
                  ),
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text('UNIKALNY KOD:', style: TextStyle(color: Colors.black)),
                      Text('e-86-tC-9', style: TextStyle(color: Colors.black))
                    ],
                  )
                  ],
                ),
                Column(
                  children: [
                    SizedBox(height: 8.0),
                    Image.asset('assets/images/coupon_hamburger.png',)
                  ],
                )
              ],
            )
      ),
    )));
  }
}

Upvotes: 5

Views: 9549

Answers (3)

Yousuf Ali
Yousuf Ali

Reputation: 408

We can achieve this with animated container widget. We have to make a custom AnimatedAppBar widget that manages the animation.

  class AnimatedAppBar extends StatelessWidget implements PreferredSizeWidget { //implements PreferredSizeWidget
  const AnimatedAppBar({super.key, required this.showAppBar});

  final bool showAppBar;

  @override
  Widget build(BuildContext context) {
    return AnimatedContainer(
      // when showAppBar value is true appbar will show with animation
      // when showAppBar value is false appbar will hide with animation
      height: showAppBar ? kToolbarHeight : 0,
      //adjust your duration
      duration: const Duration(milliseconds: 400),
      child: AppBar(),
    );
  }

  @override
  Size get preferredSize => const Size.fromHeight(kToolbarHeight);
}

Upvotes: 3

divyanshu bhargava
divyanshu bhargava

Reputation: 1585

One way of doing it is by using stack and AnimatedBuilder.

enter image description here

class GeneratedCouponScreen extends StatefulWidget {
  @override
  _GeneratedCouponScreenState createState() => _GeneratedCouponScreenState();
}

class _GeneratedCouponScreenState extends State<GeneratedCouponScreen>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 300),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: SafeArea(
        child: AnimatedBuilder(
          animation: _controller,
          builder: (context, child) => Stack(
            children: <Widget>[
              Transform.translate(
                offset: Offset(0, -_controller.value * 64),
                child: Container(
                  height: 56.0,
                  child: AppBar(
                    title: Text('Title'),
                    leading: Icon(
                      Icons.arrow_back,
                    ),
                  ),
                ),
              ),
              GestureDetector(
                onDoubleTap: () {
                  if (_controller.isCompleted) {
                    _controller.reverse();
                  } else {
                    _controller.forward();
                  }
                },
                child: Container(
                  margin: const EdgeInsets.only(top: 56.0),
                  padding: EdgeInsets.all(16.0),
                  child: Column(
                    children: [
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text(
                                'DATA WYDANIA:',
                                style: TextStyle(color: Colors.black),
                              ),
                              Text('10/09/2019',
                                  style: TextStyle(color: Colors.black))
                            ],
                          ),
                          Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              Text('UNIKALNY KOD:',
                                  style: TextStyle(color: Colors.black)),
                              Text('e-86-tC-9',
                                  style: TextStyle(color: Colors.black))
                            ],
                          )
                        ],
                      ),
                      Column(
                        children: [
                          SizedBox(height: 8.0),
                          Image.network(
                            'http://via.placeholder.com/640x360',
                          )
                        ],
                      )
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Upvotes: 6

Constantin N.
Constantin N.

Reputation: 2839

First you have to create a new class

class MyAppBar extends StatefulWidget implements PreferredSizeWidget {


num height = 70.0;
  @override
  _MyAppBarState createState() => _MyAppBarState();

  @override
  Size get preferredSize => Size.fromHeight(height);
}

class _MyAppBarState extends State<MyAppBar> {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: GestureDetector(
        onDoubleTap: () {
          // Your logic here
          // You can do any stuff like animating your this appBar
          //e.g: using Opacitiy or Transform and any other Widget depending on what kind of animation you want
          // You can also descrease height by calling widget.height
        },
        child: AppBar(
            //Your logic here
            ),
      ),
    );
  }
}

Then call it like this

 return Scaffold(
  appBar: MyAppBar(),);

Upvotes: 1

Related Questions