Анимированная панель приложений с NotificationListener во флаттере - PullRequest
0 голосов
/ 21 апреля 2020

Я хочу анимировать высоту моей панели приложений во Flutter, используя NotificationListener & ScrollController, но, похоже, она не работает. Я знаю, что что-то упустил, мне нужна помощь в выяснении этого.

Вот что у меня есть,

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

Должно быть так, что если пользователь прокручивает вниз , я хочу, чтобы высота панели приложения и высота нижней панели были анимированными (уменьшить) и наоборот, если пользователь прокручивает вверх .

1 Ответ

1 голос
/ 22 апреля 2020

Вы можете скопировать и запустить полный код ниже
Вам необходимо следующее

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

рабочая демонстрация

enter image description here

полный код

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