AnimationBuilder로 만드는 펑펑 튀는 Widget
12303 단어 FlutterWebFlutter
자연스럽게 유저의 주의를 끌고 싶을 때, 뛰어넘어 어필하는 것이 유효합니다
MacOS의 Dock에서도 백그라운드에서 업데이트 된 앱이 흠뻑 튀어 나올 수 있습니다.
많이 사용하면 눈에 띄지만 포인트로 사용하면 유효할까 생각합니다
이번에는 Flutter의 AnimationBuilder를 사용하여 임의의 Widget을 튕겨내는 컨테이너 클래스를 작성해 보았습니다.
Flutter의 애니메이션 유형
공식 문서 에서, 차트 첨부로 해설하고 있습니다. 친절합니다.
이번 경우에는
라고 말하면 TweenAnimationBuilder를 사용하기로 결정했습니다.
단순히 크게 or 작게 하거나, 한 방향으로 움직이는 것 같은 애니메이션이라면, AnimatedContainer 쪽이 간편할 것 같습니다. 뛰어오르는 동작의 경우는, 날아, 떨어진다, 라고 하는 2 액션이 필요하므로 AnimatedContainer에서는 구현이 어려울 것 같았습니다
펑펑 뛰어 넘는 Container 구현
라고 말하는 것으로 구현해 본 것이 이쪽입니다
소스 코드
bounce_container.dartimport 'package:flutter/cupertino.dart';
// ========== アニメーション定義 ========== //
// 飛び上がりアニメーション
final _bounceUp = TweenSequenceItem<double>(
weight: 1,
tween: Tween(
begin: 0.0, end: -30.0
).chain(CurveTween(curve: Curves.easeOutCubic))
);
// 飛び下がりアニメーション
final _bounceDown = TweenSequenceItem<double>(
weight: 1,
tween: Tween(
begin: -30.0, end: 0.0
).chain(CurveTween(curve: Curves.easeInCubic))
);
// 有限回数繰り返すために、TweenSequenceでその分定義する
final _sequence = TweenSequence<double>(
<TweenSequenceItem<double>>[
_bounceUp,
_bounceDown,
_bounceUp,
_bounceDown,
_bounceUp,
_bounceDown
]
);
// ========== Widget定義 ========== //
class BounceContainer extends StatefulWidget {
final Widget child;
final state = _BounceContainerState();
BounceContainer({required this.child});
@override
State<StatefulWidget> createState() => state;
// 外部からアニメーションをトリガーするための公開メソッド
void bounce() {
state.animate();
}
}
// Stateful WidgetかつSingleTickerProviderStateMixinが必要
class _BounceContainerState extends State<BounceContainer> with SingleTickerProviderStateMixin {
late AnimationController animController;
late Animation<double> animTween;
@override
void initState() {
super.initState();
animController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 2000),
);
animTween = _sequence.animate(animController);
}
@override
void dispose () {
animController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: animController,
builder: (context, child) {
return Transform.translate(
offset: Offset(0, animTween.value),
child: widget.child);
}
);
}
void animate() {
animController.reset(); // resetしないと2回目以降に動かない
animController.forward();
}
}
사용하는 쪽 소스 코드
FloatingActionButton을 누르면 흠뻑 빠집니다.
main.dartclass MyHomePage extends StatelessWidget {
final bounceIcon = BounceContainer(
child: Icon(Icons.tag_faces)
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
toolbarHeight: 0,
),
body: Center(
child: bounceIcon,
),
floatingActionButton: FloatingActionButton(
onPressed: () {
bounceIcon.bounce();
},
child: Icon(Icons.repeat),
),
);
}
}
애니메이션 유형으로 대공 시간 조정
TweenSequence의 Curves를 사용하면 펑펑 상태를 조정할 수 있습니다.
Curves 애니메이션 패턴은 공식적으로
import 'package:flutter/cupertino.dart';
// ========== アニメーション定義 ========== //
// 飛び上がりアニメーション
final _bounceUp = TweenSequenceItem<double>(
weight: 1,
tween: Tween(
begin: 0.0, end: -30.0
).chain(CurveTween(curve: Curves.easeOutCubic))
);
// 飛び下がりアニメーション
final _bounceDown = TweenSequenceItem<double>(
weight: 1,
tween: Tween(
begin: -30.0, end: 0.0
).chain(CurveTween(curve: Curves.easeInCubic))
);
// 有限回数繰り返すために、TweenSequenceでその分定義する
final _sequence = TweenSequence<double>(
<TweenSequenceItem<double>>[
_bounceUp,
_bounceDown,
_bounceUp,
_bounceDown,
_bounceUp,
_bounceDown
]
);
// ========== Widget定義 ========== //
class BounceContainer extends StatefulWidget {
final Widget child;
final state = _BounceContainerState();
BounceContainer({required this.child});
@override
State<StatefulWidget> createState() => state;
// 外部からアニメーションをトリガーするための公開メソッド
void bounce() {
state.animate();
}
}
// Stateful WidgetかつSingleTickerProviderStateMixinが必要
class _BounceContainerState extends State<BounceContainer> with SingleTickerProviderStateMixin {
late AnimationController animController;
late Animation<double> animTween;
@override
void initState() {
super.initState();
animController = AnimationController(
vsync: this,
duration: Duration(milliseconds: 2000),
);
animTween = _sequence.animate(animController);
}
@override
void dispose () {
animController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: animController,
builder: (context, child) {
return Transform.translate(
offset: Offset(0, animTween.value),
child: widget.child);
}
);
}
void animate() {
animController.reset(); // resetしないと2回目以降に動かない
animController.forward();
}
}
class MyHomePage extends StatelessWidget {
final bounceIcon = BounceContainer(
child: Icon(Icons.tag_faces)
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
toolbarHeight: 0,
),
body: Center(
child: bounceIcon,
),
floatingActionButton: FloatingActionButton(
onPressed: () {
bounceIcon.bounce();
},
child: Icon(Icons.repeat),
),
);
}
}
Reference
이 문제에 관하여(AnimationBuilder로 만드는 펑펑 튀는 Widget), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/nashitake/items/f5c486d573d715249268텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)