스마트시대
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:41728x90
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
반응형
'Programing > Flutter' 카테고리의 다른 글
Comments