Reputation: 1167
I want to animate the height of my AppBar in Flutter using NotificationListener & ScrollController, but it doesn't seem to work. I know i'm missing something, i need help figuring it out.
Here's what i have,
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()),
),
),
),
),
);
}
}
It should be that if user scrolls down, i want the appbar height and bottom bar height to be animated (reduce) & vice versa if user scrolls up.
Upvotes: 1
Views: 1345
Reputation: 54427
You can copy paste run full code below
You need the following
animation.addListener(() {
setState(() {});
});
working demo
full code
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()),
),
),
),
),
);
}
}
Upvotes: 2