Add animation to group change.
This commit is contained in:
parent
e9e27d8cb6
commit
5d940a6342
|
@ -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();
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue