-
좋아요 인터렉션을 참고해 만든 커스텀 인터렉션IT/Flutter 2024. 6. 12. 15:59SMALL
사내에서 인스타 라이브의 좋아요 인터렉션을 응용하면 구현이 가능할만한 인터렉션 요소를 개발해달라는 요구가 들어와서 한번 공유해보고자 한다.
먼저 맨 아래의 [인스타 라이브의 좋아요 인터렉션] 블로그 글을 참고하면 이해하는데 더욱 도움이 될 것 같다.
구현 프로세스
1. 아이콘 터치
2. 터치 위치에 인터렉션 요소를 가진 아이템 추가
3. 애니메이션 종료
4. 아이템 삭제* 터치 및 해당 위치에 인터렉션 요소를 가진 아이템 추가
터치 위치값을 알기 위해선 GestureDetector 의 onTapDown 콜백 메서드를 활용할 수 있다.
localPostion 과 globalPosition 을 가져올 수 있는데,
globalPostion - 전체 스크린 영역에서 절대위치 값
localPosition - 탭 한 위젯 내에서의 상대적인 위치 값
정도로 이해할 수 있다.
어떤 position 을 사용해서 구현해도 무방하지만 나는 커다란 코인버튼 영역 내에서 생성되기를 원했기 때문에 localPosition을 이용하여 구현하였다.
onTapDown: (details) { final localPosition = details.localPosition; addTouchInteractionIcon(localPosition); widget.onTap.call(); setState(() {}); },
void addTouchInteractionIcon(Offset tapPosition) { touchInteractionIcons = [ ...touchInteractionIcons, _TouchInteractionIcon( key: UniqueKey(), tapPosition: tapPosition, onAnimationEnd: () { _removeTouchInteractionIcon(touchInteractionIcons); }, ) ]; }
이렇게 position 값을 얻어왔다면 해당 위치에 인터렉션 아이콘을 삽입해준다.
여기서 주의할 점은 Flutter 프레임워크가 새로 추가된 인터렉션 아이템의 renderobject 를 재사용하게 하면 안된다는 것이다.
해당 인터렉션 아이템은 생성되는 즉시 TransForm 위젯을 이용하여 위치를 이동하고 transition, opacity, scale 등의 애니메이션을 animationController 을 통해 수행하게 되는데, 재사용을 하게되면 원치않는 인터렉션이 생길수가있다.
Flutter 프레임워크에서 트리내의 위젯의 재사용을 결정하는 방식은 크게 두가지가 있는데,
먼저 key 가 주어지지 않은 경우 해당 위치의 위젯의 Type 을 이용하여 비교한다.
만약 key가 주어진다면 type과 함께 key를 이용하여 비교한다.
따라서 Type 은 같을 수 밖에 없으므로 프레임워크 내부적으로 중복되지않는 키값을 생성해주는 UniqueKey() 메서드를 이용하여 key를 넘겨주게 되면 위와같은 현상을 방지할 수 있다.
* 인터렉션 아이템
class _TouchInteractionIcon extends HookWidget { const _TouchInteractionIcon({required this.tapPosition, required this.onAnimationEnd, super.key}); final VoidCallback onAnimationEnd; final Offset tapPosition; @override Widget build(BuildContext context) { final animationController = useAnimationController( duration: const Duration(milliseconds: 1000), ); final initialRotationAngle = useState(_getRotationAngle()); final initialScale = useState(_getInitialScale()); final initialXPosition = useState(tapPosition.dx + Random().nextInt(20) - 58.w); useEffect(() { Future.microtask(() { animationController.addStatusListener((status) { if (status == AnimationStatus.completed) { onAnimationEnd.call(); } }); animationController.forward(); }); () => null; }, []); return AnimatedBuilder( animation: animationController, builder: (context, child) { return Opacity( opacity: _getOpacity(animationController.value), child: Transform( transform: Matrix4.translationValues( ...)
인터렉션 아이템 내부에서는 생성과 동시에 초기 위치, 스케일 등의 인터렉션에 필요한 요소들을 초기화해주고, 애니메이션을 실행하며 Transform 으로 위치를 이동시키고 있다.
이에 더하여 원하는 애니메이션 요소들을 추가해주면 더욱 더 멋진 인터렉션을 만들 수 있을것이다.* 참고
[Flutter] 인스타 라이브의 좋아요 인터렉션
인스타 라이브의 좋아요 인터렉션은 어떻게 만들까?
velog.io
LIST'IT > Flutter' 카테고리의 다른 글
Flutter 에서 Element 와 RenderObject 를 재사용하는 방법 (0) 2024.02.24 [Flutter] Vertical scroll tabbar 을 만들어보자 (0) 2023.06.05 [Flutter] Expandable bottom sheet dialog 를 직접 만들어보자 (0) 2023.06.01 [Flutter] ios 빌드 시 Module "** *" not found 에러를 만날때 (1) 2023.05.15 [Flutter] RxDart 공식문서 보기 - 1 (0) 2023.01.03