#flutter #flutter-animation
#flutter #анимация flutter
Вопрос:
Я хотел бы создать пользовательский onTap
(или любой из других onTap
обратных вызовов, предоставляемых GestureDetector
«индикатором», где содержимое (дочерний элемент) уменьшено, а текст становится темнее, например, так:
Существует ли уже готовый пакет для такого типа анимации? Если нет, можете ли вы, по крайней мере, исправить фрагмент ниже.
Я попытался создать его, используя AnimationController
, Transform.scale
и различные комбинации onTap
обратных вызовов, но он практически не реагирует (все время «зависает»)
Вот основной фрагмент:
double squareScaleA = 1;
AnimationController _controllerA;
@override
void initState() {
_controllerA = AnimationController(
vsync: this,
lowerBound: 0.9,
upperBound: 1.0,
duration: Duration(milliseconds: 100));
_controllerA.addListener(() {
setState(() {
squareScaleA = _controllerA.value;
});
});
super.initState();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTapDown: (dp) {
_controllerA.forward();
},
onTapUp: (dp) {
_controllerA.reverse();
},
child: Transform.scale(
scale: squareScaleA,
child: widget.child,
),
);
}
Ответ №1:
Я обнаружил проблему с моим кодом, анимация была «перевернута», при onTapDown это привело бы к child
расширению (ничего не произошло, поскольку child
масштаб уже был максимальным), поэтому я просто перевернул _controllerA.reverse
и _controllerA.forward
(фактически заменил _controllerA.forward
на _controllerA.fling
). Это окончательный код:
class OnTapScaleAndFade extends StatefulWidget {
final Widget child;
final void Function() onTap;
const OnTapScaleAndFade({Key key, this.child, this.onTap}) : super(key: key);
@override
_OnTapScaleAndFadeState createState() => _OnTapScaleAndFadeState();
}
class _OnTapScaleAndFadeState extends State<OnTapScaleAndFade>
with TickerProviderStateMixin {
double squareScaleA = 1;
AnimationController _controllerA;
@override
void initState() {
_controllerA = AnimationController(
vsync: this,
lowerBound: 0.98,
upperBound: 1.0,
value: 1,
duration: Duration(milliseconds: 10),
);
_controllerA.addListener(() {
setState(() {
squareScaleA = _controllerA.value;
});
});
super.initState();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
_controllerA.reverse();
widget.onTap();
},
onTapDown: (dp) {
_controllerA.reverse();
},
onTapUp: (dp) {
Timer(Duration(milliseconds: 150), () {
_controllerA.fling();
});
},
onTapCancel: () {
_controllerA.fling();
},
child: Transform.scale(
scale: squareScaleA,
child: widget.child,
),
);
}
@override
void dispose() {
_controllerA.dispose();
super.dispose();
}
}
Не стесняйтесь добавлять свои пользовательские обратные вызовы жестов, мне нужен был только onTap.
Ответ №2:
Использование zoom_tap_animation: ^1.1.0
Он обрабатывает то, что вам нужно.
Использование:
виджет ZoomTapAnimation используется по умолчанию
ZoomTapAnimation(
onTap: (){},
child: YOUR_WIDGET
);
и вы также можете определить пользовательские параметры
ZoomTapAnimation(
child: YOUR_WIDGET,
onTap: (){},
onLongTap: (){},
enableLongTapRepeatEvent: false,
longTapRepeatDuration: const Duration(milliseconds: 100),
begin: 1.0,
end: 0.93,
beginDuration: const Duration(milliseconds: 20),
endDuration: const Duration(milliseconds: 120),
beginCurve: Curves.decelerate,
endCurve: Curves.fastOutSlowIn
);
дополнительная информация здесь: https://pub.dev/packages/zoom_tap_animation
Ответ №3:
Вы можете попробовать этот пакет для паба. Вы можете изменить анимацию по своему усмотрению. С помощью scaleCoefficient вы можете регулировать скорость. Если вы обернете им виджет So, он будет выглядеть анимированным
https://pub.dev/packages/spring_button Пример;
SpringButton(
SpringButtonType.OnlyScale,
row(
"Increment",
Colors.deepPurpleAccent,
),
onTapDown: (_) => incrementCounter(),
onLongPress: () => timer = Timer.periodic(
const Duration(milliseconds: 100),
(_) => incrementCounter(),
),
onLongPressEnd: (_) {
timer?.cancel();
},
),
),
Комментарии:
1. Спасибо за ваш ответ, но данный пакет, похоже, не работает, мой дочерний виджет не будет анимироваться