Add animation to group change.

This commit is contained in:
stonegate 2020-08-19 18:09:50 +08:00
parent e9e27d8cb6
commit 5d940a6342
1 changed files with 114 additions and 68 deletions

View File

@ -30,18 +30,41 @@ class ScrollPodcasts extends StatefulWidget {
_ScrollPodcastsState createState() => _ScrollPodcastsState(); _ScrollPodcastsState createState() => _ScrollPodcastsState();
} }
class _ScrollPodcastsState extends State<ScrollPodcasts> { class _ScrollPodcastsState extends State<ScrollPodcasts>
int _groupIndex; with SingleTickerProviderStateMixin {
int _groupIndex = 0;
Future<int> getPodcastUpdateCounts(String id) async { AnimationController _controller;
var dbHelper = DBHelper(); TweenSequence _slideTween;
return await dbHelper.getPodcastUpdateCounts(id); _getSlideTween(double value) => TweenSequence<double>([
} TweenSequenceItem(
tween: Tween<double>(begin: 0.0, end: value), weight: 4 / 5),
TweenSequenceItem(tween: ConstantTween<double>(0.0), weight: 1 / 5)
]);
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_groupIndex = 0; _groupIndex = 0;
_controller =
AnimationController(vsync: this, duration: Duration(milliseconds: 125))
..addListener(() {
if (mounted) setState(() {});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed) _controller.reset();
});
_slideTween = _getSlideTween(0.0);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
Future<int> getPodcastUpdateCounts(String id) async {
var dbHelper = DBHelper();
return await dbHelper.getPodcastUpdateCounts(id);
} }
Widget _circleContainer(BuildContext context) => Container( Widget _circleContainer(BuildContext context) => Container(
@ -98,11 +121,13 @@ class _ScrollPodcastsState extends State<ScrollPodcasts> {
gravity: ToastGravity.BOTTOM, gravity: ToastGravity.BOTTOM,
); );
} else { } else {
setState(() { if (mounted) {
(_groupIndex < groups.length - 1) setState(() {
? _groupIndex++ (_groupIndex < groups.length - 1)
: _groupIndex = 0; ? _groupIndex++
}); : _groupIndex = 0;
});
}
} }
} }
}, },
@ -116,12 +141,9 @@ class _ScrollPodcastsState extends State<ScrollPodcasts> {
horizontal: 15.0), horizontal: 15.0),
child: Text( child: Text(
groups[_groupIndex].name, groups[_groupIndex].name,
style: Theme.of(context) style: context.textTheme.bodyText1
.textTheme
.bodyText1
.copyWith( .copyWith(
color: Theme.of(context) color: context.accentColor),
.accentColor),
)), )),
Spacer(), Spacer(),
Container( Container(
@ -160,8 +182,7 @@ class _ScrollPodcastsState extends State<ScrollPodcasts> {
), ),
Container( Container(
height: 70, height: 70,
color: Theme.of(context) color: context.scaffoldBackgroundColor,
.scaffoldBackgroundColor,
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
_circleContainer(context), _circleContainer(context),
@ -216,7 +237,7 @@ class _ScrollPodcastsState extends State<ScrollPodcasts> {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
GestureDetector( GestureDetector(
onVerticalDragEnd: (event) { onVerticalDragEnd: (event) async {
if (event.primaryVelocity > 200) { if (event.primaryVelocity > 200) {
if (groups.length == 1) { if (groups.length == 1) {
Fluttertoast.showToast( Fluttertoast.showToast(
@ -225,11 +246,18 @@ class _ScrollPodcastsState extends State<ScrollPodcasts> {
); );
} else { } else {
if (mounted) { if (mounted) {
setState(() { setState(
(_groupIndex != 0) () => _slideTween = _getSlideTween(20));
? _groupIndex-- _controller.forward();
: _groupIndex = groups.length - 1; await Future.delayed(
}); Duration(milliseconds: 100));
if (mounted) {
setState(() {
(_groupIndex != 0)
? _groupIndex--
: _groupIndex = groups.length - 1;
});
}
} }
} }
} else if (event.primaryVelocity < -200) { } else if (event.primaryVelocity < -200) {
@ -239,11 +267,18 @@ class _ScrollPodcastsState extends State<ScrollPodcasts> {
gravity: ToastGravity.BOTTOM, gravity: ToastGravity.BOTTOM,
); );
} else { } else {
setState(() { setState(
(_groupIndex < groups.length - 1) () => _slideTween = _getSlideTween(-20));
? _groupIndex++ await Future.delayed(
: _groupIndex = 0; Duration(milliseconds: 100));
}); _controller.forward();
if (mounted) {
setState(() {
(_groupIndex < groups.length - 1)
? _groupIndex++
: _groupIndex = 0;
});
}
} }
} }
}, },
@ -316,45 +351,56 @@ class _ScrollPodcastsState extends State<ScrollPodcasts> {
final color = final color =
podcastLocal.backgroudColor(context); podcastLocal.backgroudColor(context);
return Tab( return Tab(
child: ClipRRect( child: Transform.translate(
borderRadius: BorderRadius.all( offset: Offset(
Radius.circular(25.0)), 0,
child: Stack( _slideTween
alignment: Alignment.bottomCenter, .animate(_controller)
children: <Widget>[ .value),
LimitedBox( child: ClipRRect(
maxHeight: 50, borderRadius: BorderRadius.all(
maxWidth: 50, Radius.circular(25.0)),
child: CircleAvatar( child: LimitedBox(
backgroundColor: maxHeight: 50,
color.withOpacity(0.5), maxWidth: 50,
backgroundImage: child: CircleAvatar(
podcastLocal.avatarImage), backgroundColor:
color.withOpacity(0.5),
backgroundImage:
podcastLocal.avatarImage,
child: FutureBuilder<int>(
future:
getPodcastUpdateCounts(
podcastLocal.id),
initialData: 0,
builder: (context, snapshot) {
return snapshot.data > 0
? Align(
alignment: Alignment
.bottomCenter,
child: Container(
alignment:
Alignment
.center,
height: 10,
width: 40,
color: Colors
.black54,
child: Text('New',
style: TextStyle(
color: Colors
.red,
fontSize:
8,
fontStyle:
FontStyle
.italic)),
),
)
: Center();
}),
), ),
FutureBuilder<int>( ),
future: getPodcastUpdateCounts(
podcastLocal.id),
initialData: 0,
builder: (context, snapshot) {
return snapshot.data > 0
? Container(
alignment:
Alignment.center,
height: 10,
width: 40,
color: Colors.black54,
child: Text('New',
style: TextStyle(
color: Colors
.red,
fontSize: 8,
fontStyle:
FontStyle
.italic)),
)
: Center();
}),
],
), ),
), ),
); );