visibility_detector
패키지는 Flutter 앱에서 위젯의 가시성 변화를 감지할 수 있게 해주는 도구입니다. 이 패키지를 사용하면 특정 위젯이 화면에 표시되거나, 화면에서 사라질 때를 정확하게 알 수 있으며, 이에 따른 작업을 실행할 수 있습니다.
기능:
사용법:
1. visibility_detector
패키지를 프로젝트의 pubspec.yaml
파일에 의존성으로 추가합니다.
2. 필요한 곳에서 패키지를 임포트합니다: import 'package:visibility_detector/visibility_detector.dart';
3. VisibilityDetector
위젯을 사용하여 감지하고 싶은 위젯을 감싸줍니다.
4. VisibilityDetector
의 key
와 onVisibilityChanged
콜백을 설정합니다. onVisibilityChanged
콜백은 위젯의 가시성이 변할 때 호출됩니다.
5. 콜백 함수 내에서, 위젯의 가시성 변화에 따라 필요한 작업을 수행합니다.
VisibilityDetector(
key: Key('unique-key'),
onVisibilityChanged: (VisibilityInfo info) {
var visiblePercentage = info.visibleFraction * 100;
print('Widget is ${visiblePercentage}% visible');
},
child: YourWidget(), // 감지하고 싶은 위젯
)
이 예시에서는 YourWidget
이 화면에 얼마나 보이는지를 백분율로 계산하여 콘솔에 출력합니다. unique-key
는 각 VisibilityDetector
인스턴스를 구별하기 위한 고유한 식별자입니다.
visibility_detector
패키지는 Flutter 앱에서 위젯의 가시성을 효과적으로 관리하고, 이를 기반으로 다양한 기능을 구현할 수 있게 해주는 강력한 도구입니다.
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:tiktok_clone/constants/sizes.dart';
import 'package:video_player/video_player.dart';
import 'package:visibility_detector/visibility_detector.dart';
class VideoPost extends StatefulWidget {
final Function onVideoFinished;
final int index;
const VideoPost({
super.key,
required this.onVideoFinished,
required this.index,
});
State<VideoPost> createState() => _VideoPostState();
}
class _VideoPostState extends State<VideoPost> {
final VideoPlayerController _videoPlayerController =
VideoPlayerController.asset("assets/videos/video.mp4");
void _onVideoChange() {
if (_videoPlayerController.value.isInitialized) {
if (_videoPlayerController.value.duration ==
_videoPlayerController.value.position) {
widget.onVideoFinished();
}
}
}
void _initVideoPlayer() async {
await _videoPlayerController.initialize();
setState(() {});
_videoPlayerController.addListener(_onVideoChange);
}
void initState() {
super.initState();
_initVideoPlayer();
}
void dispose() {
_videoPlayerController.dispose();
super.dispose();
}
void _onVisibilityChanged(VisibilityInfo info) {
if (info.visibleFraction == 1 && !_videoPlayerController.value.isPlaying) {
_videoPlayerController.play();
}
}
void _onTogglePause() {
if (_videoPlayerController.value.isPlaying) {
_videoPlayerController.pause();
} else {
_videoPlayerController.play();
}
}
Widget build(BuildContext context) {
return VisibilityDetector(
key: Key("${widget.index}"),
onVisibilityChanged: _onVisibilityChanged,
child: Stack(
children: [
Positioned.fill(
child: _videoPlayerController.value.isInitialized
? VideoPlayer(_videoPlayerController)
: Container(
color: Colors.black,
),
),
Positioned.fill(
child: GestureDetector(
onTap: _onTogglePause,
),
),
const Positioned.fill(
child: IgnorePointer(
child: Center(
child: FaIcon(
FontAwesomeIcons.play,
color: Colors.white,
size: Sizes.size52,
),
),
),
)
],
),
);
}
}
이 코드는 VisibilityDetector
패키지를 사용하여 Flutter에서 비디오 포스트를 처리하는 방법을 보여줍니다. 특히, 사용자가 스크롤하여 비디오가 화면에 완전히 보이게 될 때 자동으로 재생을 시작하고, 비디오 재생이 끝나면 특정 작업(예: 콜백 함수 실행)을 수행하는 로직을 포함하고 있습니다.
VideoPlayerController:
_videoPlayerController
는 비디오 파일을 재생하기 위해 사용됩니다. 여기서는 로컬 에셋에서 비디오 파일("assets/videos/video.mp4"
)을 로드합니다._initVideoPlayer 메서드:
_onVideoChange 메서드:
_videoPlayerController.value.duration == _videoPlayerController.value.position
), widget.onVideoFinished
콜백을 실행합니다.VisibilityDetector:
VisibilityDetector
위젯은 비디오 포스트의 가시성을 감지합니다. 각 비디오 포스트에 고유한 key
를 할당하여, 스크롤 시 각 포스트의 가시성을 독립적으로 추적할 수 있습니다._onVisibilityChanged 메서드:
info.visibleFraction == 1
) 비디오가 현재 재생되고 있지 않다면(!_videoPlayerController.value.isPlaying
), 비디오 재생을 시작합니다._onTogglePause 메서드:
Widget Tree:
Stack
위젯을 사용하여 비디오 플레이어, 제스처 감지기, 재생 아이콘을 포함합니다. Positioned.fill
을 사용하여 이러한 위젯들이 전체 스택을 채우도록 합니다.IgnorePointer
는 사용자 인터페이스에서 특정 위젯(여기서는 재생 아이콘)이 포인터(예: 탭) 이벤트를 받지 않도록 합니다.이 코드는 VisibilityDetector
를 활용하여 사용자의 스크롤 동작에 따라 비디오 포스트의 재생과 일시 정지를 자동으로 제어합니다. 이를 통해 사용자 경험을 향상시키고, 앱의 성능을 최적화할 수 있습니다. 사용자가 화면에 보이는 비디오만 재생함으로써 리소스 사용을 최적화하고, 불필요한 데이터 로딩을 줄일 수 있습니다.