#flutter #flutter-layout #flutter-animation #flare
#flutter #flutter-layout #flutter-анимация #вспышка
Вопрос:
Я пытаюсь повторно воспроизвести анимацию вспышки во Flutter. Не зацикливайте анимацию, когда она завершена. Я хочу, чтобы анимация воспроизводилась по запросу, та же анимация.
Когда я переключаюсь между анимациями, это работает нормально, просто меняя строку местами и вызывая setState. Есть ли простой способ сделать это.
Вот что я сейчас делаю.
class _FlareDemoState extends State<FlareDemo> {
String animationToPlay = 'activate';
@override
Widget build(BuildContext context) {
print('Animation to play: $animationToPlay');
return Scaffold(
backgroundColor: Colors.purple,
body: GestureDetector(
onTap: () {
setState(() {
});
},
child: FlareActor('assets/button-animation.flr',
animation: animationToPlay)));
}
}
Мои логи выдаются, когда я нажимаю на анимацию
I/flutter (18959): Animation to play: activate
I/flutter (18959): Animation to play: activate
I/chatty (18959): uid=10088(com.example.flare_tutorial) Thread-2 identical 2 lines
I/flutter (18959): Animation to play: activate
I/flutter (18959): Animation to play: activate
I/chatty (18959): uid=10088(com.example.flare_tutorial) Thread-2 identical 7 lines
I/flutter (18959): Animation to play: activate
I/flutter (18959): Animation to play: activate
Reloaded 2 of 495 libraries in 672ms.
I/flutter (18959): Animation to play: activate
Все вызывается, оно воспроизводится в первый раз, но после этого анимация не воспроизводится.
Ответ №1:
Более чистый способ сделать это — использовать пользовательский FlareController. Существует конкретная реализация FlareControls, которая хорошо подходит для этого варианта использования.
class _MyHomePageState extends State<MyHomePage> {
// Store a reference to some controls for the Flare widget
final FlareControls controls = FlareControls();
void _playSuccessAnimation() {
// Use the controls to trigger an animation.
controls.play("success");
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: FlareActor("assets/Teddy.flr",
animation: "idle",
fit: BoxFit.contain,
alignment: Alignment.center,
// Make sure you use the controls with the Flare Actor widget.
controller: controls),
floatingActionButton: FloatingActionButton(
onPressed: _playSuccessAnimation,
tooltip: 'Play',
child: Icon(Icons.play_arrow),
),
);
}
}
Обратите внимание, что в этом примере также воспроизводится фоновая анимация в режиме ожидания, которая зацикливается. Любой вызов FlareControls.воспроизведение смешает входящую анимацию с этой фоновой анимацией ожидания. Вы просто опускаете аргумент animation: «idle», если вы не хотите / нуждаетесь в фоновой анимации.
Полный пример здесь:https://github.com/luigi-rosso/flare_controls
Комментарии:
1. Оооооооо, это выглядит намного лучше. По какой-то причине я не смог найти ничего подобного. Позвольте мне реализовать это таким образом и посмотреть, работает ли это. Я вернусь к вам через некоторое время.
2. это намного лучшее решение, чем мое. Спасибо.
Ответ №2:
Основываясь на ответе от @Eugene, я придумал временное решение. Я установил значение пустым, запустил таймер на 50 мс, а затем вернул значение анимации, которую я хотел воспроизвести снова.
class _FlareDemoState extends State<FlareDemo> {
String animationToPlay = 'activate';
@override
Widget build(BuildContext context) {
print('Animation to play: $animationToPlay');
return Scaffold(
backgroundColor: Colors.purple,
body: GestureDetector(
onTap: () {
_setAnimationToPlay('activate');
},
child: FlareActor('assets/button-animation.flr',
animation: animationToPlay)));
}
}
void _setAnimationToPlay(String animation) {
if (animation == _animationToPlay) {
_animationToPlay = '';
Timer(const Duration(milliseconds: 50), () {
setState(() {
_animationToPlay = animation;
});
});
} else {
_animationToPlay = animation;
}
}
Это грязный обходной путь, но он выполняет свою работу. Спасибо @Eugene за посев семян.
Комментарии:
1. большой палец вверх за использование таймера. Я хотел прекратить воспроизведение анимации через 1 секунду. Помог таймер.
Ответ №3:
FlareActor(
"assets/animation/day_night.flr",
alignment: Alignment.center,
fit: BoxFit.cover,
animation: _animation,
callback: (string) {
if(string=="switch_night"){
setState(() {
_animation = _animationNight;
});
}else if(string=="switch_day"){
setState(() {
_animation = _animationDay;
});
}
},
)