如何在Flutter中制作隐藏AppBar的动画?

5

我需要帮助来实现我的AppBar动画。

我的AppBar在双击时会隐藏,但是它没有动画效果,会立即隐藏。我希望能够添加动画效果。我尝试使用SlideTransition和AnimatedContainer小部件包装我的AppBar,但这两种方法都不起作用,因为报错提示我需要一个PreferredSize小部件。

如果有人能帮助我,我将非常高兴!

我已经查看了这个答案,但是回答这个问题的人也遇到了同样的问题。没有动画效果。 Show (slide in) or hide (slide out) flutter AppBar on screen tap

这里是我的AppBar的视频:https://streamable.com/it7ib

这里是我的AppBar的照片:flutter

代码:

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',)
                  ],
                )
              ],
            )
      ),
    )));
  }
}

https://dev59.com/r7Dla4cB1Zd3GeqP2hNz - Amit Prajapati
是的,我也找到了这个答案,但是回答这个问题的人有同样的问题。他的AppBar中没有动画,而且他和我做的一样。我应该指出我已经找到了那个答案。 - szakes1
1
所以你可以使用PreferredSize小部件:appBar: PreferredSize( preferredSize: Size.fromHeight(50.0), // 这里是所需的高度 child: AppBar( // ... ) ),我认为在应用PreferredSize小部件后,您将能够使您的AppBar动画化。 - Mo Meshkani
3个回答

6

使用堆栈(Stack)和AnimatedBuilder是一种实现方法。

输入图像描述

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',
                          )
                        ],
                      )
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

抱歉回复有些晚了,但我仍然有一个问题。在隐藏这个AppBar之后,如何将下面的内容向上移动? - szakes1
好的,有多种方法。其中一种方法可以是像应用栏一样翻译所有小部件。 - divyanshu bhargava

0

首先,您需要创建一个新类

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
            ),
      ),
    );
  }
}

然后像这样调用它

 return Scaffold(
  appBar: MyAppBar(),);

0
我们可以通过动画容器小部件来实现这一点。我们需要创建一个自定义的AnimatedAppBar小部件来管理动画。
  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);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接