미해결
[코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!
Video Player 프로젝트에 대한 추가 질문
선생님 강의 너무 잘 듣고 있습니다.video_player 프로젝트 관련 내용 모두 확인했고, 여기에 하나만 간단하게 비디오에서 나가기 버튼을 추가해보았습니다. 일단 제가 작성해본 코드부터 공유하겠습니다.테스트 상 로고화면으로는 잘 돌아갑니다. _VideoPlayerState의 dispose() 함수도 정상적으로 실행돼요. 다만 로직이 실제 앱에서 실행되어도 충분히 괜찮은 로직일지, 혹은 더 안전한 방법이나 기타 필요한 수정사항이 있다면 알려주시면 감사하겠습니다. _HomeScreenState 내부class _HomeScreenState extends State<HomeScreen> {
// bool showVideo = false;
XFile? video;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black87,
body: video == null
? _VideoSelector(onLogoTap: openPicker)
: _VideoPlayer(
video: video!,
onImageIconPressed: openPicker,
onExitIconPressed: exitPlayer, // 나가기 버튼 함수
),
);
}
void openPicker() async {
// setState(() => showVideo = true);
/// ImageSource.gallary: 사진 앱에 저장된 이미지/비디오 파일 선택
/// ImageSource.camera: 디바이스가 즉시 촬영한 이미지/비디오 파일 선택
const source = ImageSource.gallery;
/// pickVideo(): 사용자 비디오 파일을 선택
final picked = await ImagePicker().pickVideo(source: source);
// print(picked);
setState(() => video = picked);
}
/// ↓↓ 여기에 비디오에서 나가기 로직 추가
void exitPlayer() {
setState(() {
// print('info: exitIconButton 클릭');
video = null;
});
}
} _VideoPlayerState 내부class _VideoPlayerState extends State<_VideoPlayer> {
late VideoPlayerController _videoPlayerController;
bool showButton = true;
// ...
/// 위젯 상태 제거
@override
void dispose() {
_videoPlayerController.dispose();
print('info: 비디오 플레이어 종료 중..');
super.dispose();
}
@override
Widget build(BuildContext context) {
final VideoPlayerValue videoPlayer = _videoPlayerController.value;
// final position = videoPlayer.position;
// final duration = videoPlayer.duration;
return Center(
child: AspectRatio(
aspectRatio: videoPlayer.aspectRatio,
child: GestureDetector(
onTap: () => setState(() => showButton = !showButton),
child: Stack(
children: <Widget>[
VideoPlayer(_videoPlayerController),
/// 영상 화면 커버
if (showButton)
Container(
width: double.infinity,
height: double.infinity,
color: Colors.black.withAlpha(128),
),
/// 재생/중지와 뒤로&앞으로 버튼
if (showButton)
_PlayButton(
isPlaying: videoPlayer.isPlaying,
onReversePressed: onReversePressed,
onPlayPressed: onPlayPressed,
onForwardPressed: onForwardPressed,
),
/// 하단 슬라이더
if (showButton)
_BottomSlider(
position: videoPlayer.position,
duration: videoPlayer.duration,
onSliderMoved: onSliderMoved,
),
/// 화면 상단 버튼
if (showButton)
_TopButtons( // ← 여기를 2개의 버튼으로 확장
onExitPressed: widget.onExitIconPressed,
onImagePressed: widget.onImageIconPressed,
),
],
),
),
),
);
} _TopButtons 내부class _TopButtons extends StatelessWidget {
final VoidCallback onImagePressed;
final VoidCallback onExitPressed;
const _TopButtons({
required this.onExitPressed,
required this.onImagePressed,
});
@override
Widget build(BuildContext context) {
return Positioned(
left: 4,
right: 4,
top: 0,
// Row로 감싸고 왼쪽에 '나가기' 버튼 추가
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <IconButton>[
// 나가기 버튼
IconButton(
onPressed: onExitPressed,
icon: Icon(Icons.chevron_left, color: Colors.white),
),
// 다른 영상 선택 버튼
IconButton(
onPressed: onImagePressed,
icon: Icon(Icons.photo_camera_back, color: Colors.white),
),
],
),
);
}
}