스마트시대

21 MVVM 21.2 VideoPlaybackConfigRepository 21.3 PlaybackConfigViewModel 21.4 Views 본문

Programing/Flutter

21 MVVM 21.2 VideoPlaybackConfigRepository 21.3 PlaybackConfigViewModel 21.4 Views

스마트시대 2023. 5. 28. 18:41
728x90

21.1 MVVM

Home화면에서

View: 영상 타임라인(스크롤 이벤트 발생시킴)

ViewModel: API한테 데이터를 요청하는 부분(View가 페이지가 더 필요해서 페이지를 더 요청해 데이터 받음, 화면으로부터 이벤트를 받고 데이터 수정하고 화면에 알려줘서 데이터의 변화를 반영한다.)

Model:영상에 대한 모델을 build한다.(Json으로 이루어짐)

그 다음에 그 영상들을 view한테 넘겨주고

View가 무한 스크롤로 그 영상을 보여줌.

 

 

Repository: 완전히 별도의 파일, 별도의 클래스로써 유일한 역할은 데이터 저장하는 것(기기 저장소에 저장을 하는 역할)

Repository가 firebase와 통신함(View, ViewModel는 firebase와 통신하지 않음)

21.2 VideoPlaybackConfigRepository

 

절대 경로로 import

 

shared_preferences: ^2.0.17

강의상은 이거

 

 

 

21.3 PlaybackConfigViewModel 

      DeviceOrientation.portraitUp,
    ],
  );
  
  
--------------------
//(21.3)
  final preferences = await SharedPreferences.getInstance();
  final repository = PlaybackConfigRepository(preferences);
--------------------


// dart모드 관련 설정:
  // SystemChrome.setSystemUIOverlayStyle(
  //   SystemUiOverlayStyle.dark,
  // );
  // runApp(const TikTokApp());
  
--------------------
  //(21.3)
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (context) => PlaybackConfigViewModel(repository),
        ),
      ],
      child: const TikTokApp(),
    ),
  );
}
--------------------


class TikTokApp extends StatelessWidget {
  const TikTokApp({super.key});
  
    @override
  Widget build(BuildContext context) {
  --------------------
      //(21.3)
    return MaterialApp.router(
      routerConfig: router,
      debugShowCheckedModeBanner: false,
      title: 'TikTok Clone',
--------------------


      // 번역 관련 delegate(번역파일) 설치
      localizationsDelegates: const [

import 'package:flutter/material.dart';
import 'package:tiktok_clone/features/videos/models/playback_config_model.dart';
import 'package:tiktok_clone/features/videos/repos/playback_config_repo.dart';

class PlaybackConfigViewModel extends ChangeNotifier {
  //(21.3)
  final PlaybackConfigRepository _repository;

  late final PlaybackConfigModel _model = PlaybackConfigModel(
    muted: _repository.isMuted(),
    autoplay: _repository.isAutoplay(),
  );

  PlaybackConfigViewModel(this._repository);

  bool get muted => _model.muted;

  bool get autoplay => _model.autoplay;

  void setMuted(bool value) {
    _repository.setMuted(value); // repository에서 값을 디스크에 persist(지속)하게 저장
    _model.muted = value; //model 수정
    notifyListeners(); //listen하고 있는 모두에게 notify해줌
  }

  void setAutoplay(bool value) {
    _repository.setAutoplay(value);
    _model.autoplay = value;
    notifyListeners();
  }
}

context.watch<>: 보고 수정해준다.

context.read<>:읽기 전용

여기서 <>는 타입을 의미한다.

 

 

21.4 Views

 

 

      vsync: this,
      lowerBound: 1.0,
      upperBound: 1.5,
      //디폴트 표시
      value: 1.5,
      duration: _animationDuration,
    );

----------------
//(21.4)볼륨 음소거 함수(진짜)
    context
        .read<PlaybackConfigViewModel>()
        .addListener(_onPlaybackConfigChanged);
  }
----------------


 super.dispose();
  }


----------------
  //(21.4)볼륨 음소거 메소드(진짜)
  void _onPlaybackConfigChanged() {
    if (!mounted) return;
    final muted = context.read<PlaybackConfigViewModel>().muted;
    if (muted) {
      _videoPlayerController.setVolume(0);
    } else {
      _videoPlayerController.setVolume(1);
    }
  }
----------------


// 비디오가 보여지는 영역을 계산하고 한쪽에서만 영상 재생되도록 해주는 파라메터
  void _onVisibilityChanged(VisibilityInfo info) {
    // mounted property: 위젯이 마운트되었는지 아닌지 알려줌
    if (!mounted) return;

    if (info.visibleFraction == 1 &&
        !_isPaused &&
        !_videoPlayerController.value.isPlaying) {
        
        
        ----------------
      //(21.4)볼륨 음소거 (진짜)
      final autoplay = context.read<PlaybackConfigViewModel>().autoplay;
      if (autoplay) {
        _videoPlayerController.play();
        ----------------
        
      }
    }
          Positioned(
            left: 20,
            top: 40,
            -----------------
            
            
            
            child: IconButton(
              //음량 음소거 설정 함수(20.6), VideoConfig위젯에 접근할 수 있게 해줌
              icon: FaIcon(
                //(21.4)
                context.watch<PlaybackConfigViewModel>().muted
                    ? FontAwesomeIcons.volumeOff
                    : FontAwesomeIcons.volumeHigh,
                color: Colors.white,
              ),
              onPressed:
                  //(21.4)
                  () {
                //함수 정의라서 사용자가 누를 때만 반응하면 되니 read로 충분
                context
                    .read<PlaybackConfigViewModel>()
                    .setMuted(!context.read<PlaybackConfigViewModel>().muted);
              },
            ),
          ),
          -----------------
          
          
          Positioned(
            bottom: 20,

밑에 두 버튼 누르면 비디오가 재생되지 않는 슬라이드가 넘어가는 걸 볼 수 있다.

 

728x90
반응형
Comments