繁体   English   中英

在 Flutter 中使用 NotificationListener 为自定义 Appbar 设置动画

[英]Animate Custom Appbar with NotificationListener in Flutter

我想使用 NotificationListener 和 ScrollController 在 Flutter 中为我的 AppBar 的高度设置动画,但它似乎不起作用。 我知道我遗漏了一些东西,我需要帮助弄清楚。

这就是我所拥有的,

class SampleApp extends StatefulWidget {
  @override
  _SampleAppState createState() => _SampleAppState();
}
class _SampleAppState extends State<SampleApp> with TickerProviderStateMixin {
  Animation<double> animation;
  AnimationController _controller;
  ScrollController _scrollController;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this, duration: Duration(milliseconds: 240));
    animation = Tween(begin: kToolbarHeight, end: 0.0).animate(_controller);
    _scrollController = ScrollController();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: PreferredSize(
        child: Container(color: Colors.red),
        preferredSize: Size.fromHeight(animation.value),
      ),
      bottomNavigationBar: Container(height: animation.value, color: Colors.red),
      floatingActionButton: Container(
        width: 50.0,
        height: 50.0,
        child: Center(
          child: FittedBox(
            child: FloatingActionButton(
              onPressed: () {},
              child: Icon(Icons.arrow_upward),
            ),
          ),
        ),
      ),
      body: NotificationListener(
        onNotification: (notification) {
          if (_scrollController.position.userScrollDirection == ScrollDirection.reverse) {
            _controller.forward();
            return true;
          }
          if (_scrollController.position.userScrollDirection == ScrollDirection.forward) {
            _controller.reverse();
            return true;
          }
          return false;
        },
        child: ListView(
          controller: _scrollController,
          children: List.generate(
              200,
              (index) => ListTile(
                    title: Text(index.toString()),
                  ),
          ),
        ),
      ),
    );
  }
}

应该是,如果用户向下滚动,我希望应用栏高度和底部栏高度动画(减少) ,反之亦然,如果用户向上滚动

您可以在下面复制粘贴运行完整代码
你需要以下

animation.addListener(() {
      setState(() {});
    });

工作演示

在此处输入图像描述

完整代码

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: SampleApp(),
    );
  }
}

class SampleApp extends StatefulWidget {
  @override
  _SampleAppState createState() => _SampleAppState();
}

class _SampleAppState extends State<SampleApp> with TickerProviderStateMixin {
  Animation<double> animation;
  AnimationController _controller;
  ScrollController _scrollController;

  @override
  void initState() {
    super.initState();
    print("$kToolbarHeight");
    _controller =
        AnimationController(vsync: this, duration: Duration(milliseconds: 240));
    animation = Tween(begin: kToolbarHeight, end: 0.0).animate(_controller);
    _scrollController = ScrollController();
    animation.addListener(() {
      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: PreferredSize(
        child: Container(color: Colors.red),
        preferredSize: Size.fromHeight(animation.value),
      ),
      bottomNavigationBar:
          Container(height: animation.value, color: Colors.red),
      floatingActionButton: Container(
        width: 50.0,
        height: 50.0,
        child: Center(
          child: FittedBox(
            child: FloatingActionButton(
              onPressed: () {},
              child: Icon(Icons.arrow_upward),
            ),
          ),
        ),
      ),
      body: NotificationListener(
        onNotification: (notification) {
          if (_scrollController.position.userScrollDirection ==
              ScrollDirection.reverse) {
            print("reverse");
            _controller.forward();
            return true;
          }
          if (_scrollController.position.userScrollDirection ==
              ScrollDirection.forward) {
            print("forward");
            _controller.reverse();
            return true;
          }
          return false;
        },
        child: ListView(
          controller: _scrollController,
          children: List.generate(
            200,
            (index) => ListTile(
              title: Text(index.toString()),
            ),
          ),
        ),
      ),
    );
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM