강의

멘토링

커뮤니티

인프런 커뮤니티 질문&답변

Ryu님의 프로필 이미지
Ryu

작성한 질문수

[코드팩토리] [초급] Flutter 3.0 앱 개발 - 10개의 프로젝트로 오늘 초보 탈출!

Video Player 프로젝트에 대한 추가 질문

작성

·

19

0

선생님 강의 너무 잘 듣고 있습니다.

video_player 프로젝트 관련 내용 모두 확인했고, 여기에 하나만 간단하게 비디오에서 나가기 버튼을 추가해보았습니다.

 

일단 제가 작성해본 코드부터 공유하겠습니다.

테스트 상 로고화면으로는 잘 돌아갑니다. _VideoPlayerStatedispose() 함수도 정상적으로 실행돼요.

다만 로직이 실제 앱에서 실행되어도 충분히 괜찮은 로직일지,

혹은 더 안전한 방법이나 기타 필요한 수정사항이 있다면 알려주시면 감사하겠습니다.

 

  1. _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;
        });
      }
    }  

 

  1. _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,
                    ),
                ],
              ),
            ),
          ),
        );
      }

 

  1. _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),
              ),
            ],
          ),
        );
      }
    }

 

 

답변

답변을 기다리고 있는 질문이에요
첫번째 답변을 남겨보세요!
Ryu님의 프로필 이미지
Ryu

작성한 질문수

질문하기