我想设置日历效果的动画,以便在其中上下滑动页面。上下滑动都可以,但是当我更改垂直滑动的方向时,即使我仍在触摸屏幕,也将调用DragEndDetails类。因此,触发了一种方法,该方法会自动切换到错误的页面。
我已经阅读了手势检测器文档,并正在google上搜索类似的案例。可悲的是我找不到类似的情况。
with SingleTickerProviderStateMixin {
PageController _pageController;
AnimationController _controller;
Animation _animationForward;
Animation _animationReverse;
int counter = 1;
bool forward = false;
bool reverse = false;
double distance3DMatrix = 0.0005;
final double itemHeight = 250;
final double itemWidth = 200;
static const Duration _duration = Duration(milliseconds: 600);
static const Map colorList = {
1: Colors.yellow,
2: Colors.red,
3: Colors.blue,
4: Colors.grey,
5: Colors.pink,
6: Colors.deepOrange
};
@override
void initState() {
// TODO: implement initState
super.initState();
_controller = AnimationController(
vsync: this,
duration: _duration,
)..addListener(() {
});
_animationForward = Tween(begin: 0.0, end: -2.0).animate(_controller);
_animationReverse = Tween(begin: -2.0, end: 0.0).animate(_controller);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
title: Text(
'About',
style: TextStyle(color: Colors.black),
),
centerTitle: true,
leading: GestureDetector(
child: Icon(
Icons.arrow_back,
color: Colors.black,
)),
),
body: Stack(children: <Widget>[
for (int i = colorList.length; i > 0; i--)
_buildSwipeItem(i, colorList[i]),
]),
);
}
Align _buildSwipeItem(int countValue, Color color) {
return Align(
alignment: Alignment.center,
child: AnimatedBuilder(
animation: _controller,
builder: (context, child) {
return Transform(
transform: setMatrix(countValue),
child: GestureDetector(
onVerticalDragUpdate: _handleDragUpdate,
onVerticalDragEnd: _handleDragEnd,
child: Container(
height: itemHeight,
width: itemWidth,
decoration: BoxDecoration(
border: Border.all(color: Colors.black, width: 3),
color: color,
),
),
),
);
},
),
);
}
Matrix4 setMatrix(int countingValue) {
if (countingValue == counter && forward) {
return Matrix4.identity() //--> page swiped forward
..setEntry(3, 2, distance3DMatrix)
..rotateX(pi * 0.25 * _animationForward.value);
} else if (countingValue == counter - 1 && reverse) {
return Matrix4.identity() //-->page swiped back
..setEntry(3, 2, distance3DMatrix)
..rotateX(pi * 0.25 * _animationReverse.value);
} else if (countingValue < counter) {
return Matrix4.identity() //--> when page was swiped
..setEntry(3, 2, distance3DMatrix)
..rotateX(pi * -0.5);
} else {
return Matrix4.identity() //-->page default position
..setEntry(3, 2, distance3DMatrix)
..rotateX(0);
}
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
_pageController.dispose();
_controller.dispose();
}
void _handleDragUpdate(DragUpdateDetails details) {
if(details.delta.direction.toInt()<=0){
reverse=false;
forward = true;
_controller.value -= details.primaryDelta / itemHeight; //<-- Update the _animationController.value by the movement done by user.
}else{
forward=false;
reverse=true;
_controller.value += details.primaryDelta / itemHeight; //<-- Update the _animationController.value by the movement done by user.
}
}
void _handleDragEnd(DragEndDetails details) {
final double flingVelocity = details.velocity.pixelsPerSecond.dy /
itemHeight; //<-- calculate the velocity of the gesture
if (flingVelocity < 0.0&&forward) {
print('if');
_controller.fling(velocity: 2.0);
Future.delayed(_duration, () {
forward = false;
_controller.reset();
if (counter != colorList.length) {
counter++;
}
});
}
else if (flingVelocity > 0.0&&reverse) {
print('else if');
_controller.fling(velocity: 2.0);
Future.delayed(_duration, () {
reverse = false;
_controller.reset();
if (counter != 1) {
counter--;
}
});
print(counter);
}
else {
if(_controller.value>0.5&&forward){
print('else >0.5');
_controller.fling(velocity: 2.0);
if(_controller.value==1){
forward = false;
_controller.reset();
if (counter != colorList.length) {
counter++;
}
}
}else if(_controller.value<=0.5&&forward){
_controller.fling(velocity: -2.0);
Future.delayed(_duration, () {
forward = false;
_controller.reset();
});
}else if(_controller.value>0.5&&reverse) {
print('else <0.5');
_controller.fling(velocity: 2.0);
if(_controller.value==1){
reverse = false;
_controller.reset();
if (counter != 1) {
counter--;
}
}
}else if(_controller.value<=0.5){
_controller.fling(velocity: -2.0);
Future.delayed(_duration, (){
reverse=false;
_controller.reset();
});
}
print(counter);
}
}
}