스마트시대
VIDEO TIMELINE 7.1 Infinite Scrolling 7.2 PageController 7.3 Video Player 7.4 VisibilityDetector 본문
Programing/Flutter
VIDEO TIMELINE 7.1 Infinite Scrolling 7.2 PageController 7.3 Video Player 7.4 VisibilityDetector
스마트시대 2023. 5. 14. 01:03728x90
7.1 Infinite Scrolling
stf_screen.dart관련 데이터 다 지우고
main_navigation_screen.dart
@override
Widget build(BuildContext context) {
return Scaffold(
// // 선택된 탭의 페이지만 보여주기: 항상 새로운 페이지로써 표시됨
// body: screens.elementAt(_selectedIndex),
// offStage: 해당 위젯을 안 보이게 하면서 계속 존재하게 해주는 위젯
body: Stack(
children: [
---------------------
Offstage(
offstage: _selectedIndex != 0,
child: const VideoTimelineScreen(),
---------------------
),
Offstage(
offstage: _selectedIndex != 1,
child: Container(),
),

video_timeline_screen.dart 새로 만들기
import 'package:flutter/material.dart';
class VideoTimelineScreen extends StatefulWidget {
const VideoTimelineScreen({super.key});
@override
State<VideoTimelineScreen> createState() => _VideoTimelineScreenState();
}
class _VideoTimelineScreenState extends State<VideoTimelineScreen> {
@override
Widget build(BuildContext context) {
return PageView(
children: [
Container(
color: Colors.blue,
),
Container(
color: Colors.teal,
),
Container(
color: Colors.yellow,
),
Container(
color: Colors.pink,
),
],
);
}
}

참고 property
// 유용한 새 위젯
return PageView(
--------------
// 자석 같이 화면이 딱딱 달라붙는 효과
pageSnapping: false,
--------------
children: [
Container(

// 유용한 새 위젯
return PageView(
// 자석 같이 화면이 딱딱 달라붙는 효과 property
//pageSnapping: false,
-------------
// 위로 스크롤 할 수 있는 property
scrollDirection: Axis.vertical,
-------------
children: [
Container(
color: Colors.blue,
),

하지만 위 코드로 하면 퍼포먼스가 너무 떨어진다. 컨테이너 하나하나 데이터 처리하기 떄문에.
그래서 사용할게 Pageview.builder(itemBuilder: ) 이다.
import 'package:flutter/material.dart';
class VideoTimelineScreen extends StatefulWidget {
const VideoTimelineScreen({super.key});
@override
State<VideoTimelineScreen> createState() => _VideoTimelineScreenState();
}
class _VideoTimelineScreenState extends State<VideoTimelineScreen> {
List<Color> colors = [
Colors.blue,
Colors.red,
Colors.yellow,
Colors.teal,
];
@override
Widget build(BuildContext context) {
// 유용한 새 위젯
return PageView.builder(
// 자석 같이 화면이 딱딱 달라붙는 효과 property
//pageSnapping: false,
// 위로 스크롤 할 수 있는 property
scrollDirection: Axis.vertical,
itemCount: 4,
itemBuilder: (context, index) => Container(
color: colors[index],
),
);
}
}
페이지 무한으로 증식하게 해주는 세팅
import 'package:flutter/material.dart';
class VideoTimelineScreen extends StatefulWidget {
const VideoTimelineScreen({super.key});
@override
State<VideoTimelineScreen> createState() => _VideoTimelineScreenState();
}
class _VideoTimelineScreenState extends State<VideoTimelineScreen> {
------------------
int _itemCount = 4;
void _onPageChanged(int page) {
if (page == _itemCount - 1) {
_itemCount = _itemCount + 4;
colors.addAll([
Colors.blue,
Colors.red,
Colors.yellow,
Colors.teal,
]);
setState(() {});
}
}
------------------
List<Color> colors = [
Colors.blue,
Colors.red,
Colors.yellow,
Colors.teal,
];
@override
Widget build(BuildContext context) {
// 유용한 새 위젯
return PageView.builder(
// 자석 같이 화면이 딱딱 달라붙는 효과 property
//pageSnapping: false,
// 위로 스크롤 할 수 있는 property
scrollDirection: Axis.vertical,
------------------
onPageChanged: _onPageChanged,
itemCount: _itemCount,
------------------
itemBuilder: (context, index) => Container(
color: colors[index],
------------------
child: Center(
child: Text(
"Screen $index",
style: const TextStyle(fontSize: 68),
------------------
),
),
),
);
}
}

7.2 PageController
끝에 자석효과 없애고 그냥 확확 넘어가게 해주는 설정
import 'package:flutter/material.dart';
class VideoTimelineScreen extends StatefulWidget {
const VideoTimelineScreen({super.key});
@override
State<VideoTimelineScreen> createState() => _VideoTimelineScreenState();
}
class _VideoTimelineScreenState extends State<VideoTimelineScreen> {
-----------------
int _itemCount = 4;
//스크린 넘어갈 때 느려지는 효과 없애는 함수:Pageview.builder를 컨트롤 하는 파라미터
final PageController _pageController = PageController();
-----------------
void _onPageChanged(int page) {
-----------------
//스크린 넘어갈 때 느려지는 효과 없애는 함수
//curve:애니메이션의 종류
_pageController.animateToPage(
page,
duration: const Duration(microseconds: 100),
curve: Curves.linear,
);
-----------------
if (page == _itemCount - 1) {
//페이지 무한으로 증식하게 해주는 함수
_itemCount = _itemCount + 4;
colors.addAll([
Colors.blue,
Colors.red,
Colors.yellow,
Colors.teal,
]);
setState(() {});
}
}
@override
Widget build(BuildContext context) {
// 유용한 새 위젯
return PageView.builder(
-----------------
//스크린 넘어갈 때 느려지는 효과 없애는 파라미터
controller: _pageController,
-----------------
// 자석 같이 화면이 딱딱 달라붙는 효과 property
//pageSnapping: false,

7.3 Video Player
여기다가 샘플 비디오 넣어주고

puvspec.yaml에서 변경


video_post.dart
import 'package:flutter/material.dart';
class VideoPost extends StatefulWidget {
const VideoPost({super.key});
@override
State<VideoPost> createState() => _VideoPostState();
}
class _VideoPostState extends State<VideoPost> {
@override
Widget build(BuildContext context) {
return Stack(
children: [
Positioned.fill(
child: Container(
color: Colors.teal,
),
),
],
);
}
}


import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class VideoPost extends StatefulWidget {
const VideoPost({super.key});
@override
State<VideoPost> createState() => _VideoPostState();
}
class _VideoPostState extends State<VideoPost> {
--------------
//VideoPlayerController이용하기 위한 함수
final VideoPlayerController _videoPlayerController =
VideoPlayerController.asset("assets/videos/video.mp4");
//VideoPlayerController이용하기 위한 함수
void _initVideoPlayer() async {
await _videoPlayerController.initialize();
_videoPlayerController.play();
setState(() {});
}
@override
//VideoPlayerController이용하기 위한 함수1
void initState() {
super.initState();
_initVideoPlayer();
}
//VideoPlayerController이용하기 위한 함수2
@override
void dispose() {
_videoPlayerController.dispose();
}
--------------
@override
Widget build(BuildContext context) {
return Stack(
children: [
--------------
Positioned.fill(
child: _videoPlayerController.value.isInitialized
? VideoPlayer(_videoPlayerController)
: Container(
color: Colors.black,
--------------
),
),
],
);
}
}


여기에서 _pageController관련 파라메터따로 분리해주고 _onPageChanged _onVideoFinished 함수에 파라메터 적용해주기
//스크린 넘어갈 때 느려지는 효과 없애는 함수:Pageview.builder를 컨트롤 하는 파라미터
final PageController _pageController = PageController();
-----------------
//_pageController관련 파라메터
final Duration _scrollDuration = const Duration(microseconds: 150);
final Curve _scrollCurve = Curves.linear;
-----------------
void _onPageChanged(int page) {
//스크린 넘어갈 때 느려지는 효과 없애는 함수
//curve:애니메이션의 종류
_pageController.animateToPage(
page,
-----------------
duration: _scrollDuration,
curve: _scrollCurve,
-----------------
);
if (page == _itemCount - 1) {
-----------------
// 비디오가 끝나면 어떻게 처리할지의 함수
void _onVideoFinished() {
_pageController.nextPage(
duration: _scrollDuration,
curve: _scrollCurve,
);
}
-----------------
여기서 이 처리해주고

//페이지 무한으로 증식하게 해주는 파라미터
onPageChanged: _onPageChanged,
itemCount: _itemCount,
--------------
itemBuilder: (context, index) => VideoPost(
onVideoFinished:
_onVideoFinished), //VideoPost로 넘기고 onVideoFinished 처리(다음 비디오로 넘어가기)
//->VideoPost의 statefulwidget으로 넘겨줌(state한테가 아니라)
--------------
);
}
여기서 이 처리 해줌

class VideoPost extends StatefulWidget {
-----------------
//onVideoFinished 처리해주기 위한 property,statefulWideget은 여기 있는데 작업은 state에서 해줄 필요
final Function onVideoFinished;
//onVideoFinished 처리해주기 위한 property의 costructor->이거는 State<VideoPost>로 접근
//위젯 자체에 접근하게 해주는 것 밑에 만들어줄 필요,statefulWideget은 여기 있는데 작업은 state에서 해줄 필요
const VideoPost({
super.key,
required this.onVideoFinished,
});
-----------------
@override
State<VideoPost> createState() => _VideoPostState();
}
//VideoPlayerController이용하기 위한 함수2, 보고 있지 않을 때도 캐쉬 살려두기 위함
@override
void dispose() {
_videoPlayerController.dispose();
-----------------
//위젯 자체에 접근하게 해주는 것,statefulWideget은 위 있는데 작업은 state에서 해줄 필요
widget.onVideoFinished();
}
-----------------
영상이 끝났을 때를 알기 위한 event listener 작성
listener가 영상이 바뀌는 시간, 길이, 끝나는 시간 등을 모두 알려줄 수 있음
final VideoPlayerController _videoPlayerController =
VideoPlayerController.asset("assets/videos/video.mp4");
-------------------
//VideoPlayerController를 어떻게 처리해줄 지 지정하는 listener에 넣어줄 파라메터
//_videoPlayerController.value.duration(비디오길이)가 10초이고 _videoPlayerController.value.position(현재영상내의위치)이 10초이면 영상 끝냄처리
void _onVideoChange() {
if (_videoPlayerController.value.isInitialized) {
if (_videoPlayerController.value.duration ==
_videoPlayerController.value.position) {
//위젯 자체에 접근하게 해주는 것,statefulWideget은 위 있는데 작업은 state에서 해줄 필요
widget.onVideoFinished();
}
}
}
-------------------
//VideoPlayerController이용하기 위한 함수
void _initVideoPlayer() async {
//VideoPlayerController이용하기 위한 함수
void _initVideoPlayer() async {
await _videoPlayerController.initialize();
_videoPlayerController.play();
setState(() {});
-------------------
//VideoPlayerController를 어떻게 처리해줄 지 지정하는 listener
_videoPlayerController.addListener(_onVideoChange);
-------------------
}

import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
class VideoPost extends StatefulWidget {
//onVideoFinished 처리해주기 위한 property,statefulWideget은 여기 있는데 작업은 state에서 해줄 필요
final Function onVideoFinished;
//onVideoFinished 처리해주기 위한 property의 costructor->이거는 State<VideoPost>로 접근
//위젯 자체에 접근하게 해주는 것 밑에 만들어줄 필요,statefulWideget은 여기 있는데 작업은 state에서 해줄 필요
const VideoPost({
super.key,
required this.onVideoFinished,
});
@override
State<VideoPost> createState() => _VideoPostState();
}
class _VideoPostState extends State<VideoPost> {
//VideoPlayerController이용하기 위한 함수
final VideoPlayerController _videoPlayerController =
VideoPlayerController.asset("assets/videos/video.mp4");
//VideoPlayerController를 어떻게 처리해줄 지 지정하는 listener에 넣어줄 파라메터
//_videoPlayerController.value.duration(비디오길이)가 10초이고 _videoPlayerController.value.position(현재영상내의위치)이 10초이면 영상 끝냄처리
void _onVideoChange() {
if (_videoPlayerController.value.isInitialized) {
if (_videoPlayerController.value.duration ==
_videoPlayerController.value.position) {
//위젯 자체에 접근하게 해주는 것,statefulWideget은 위 있는데 작업은 state에서 해줄 필요
widget.onVideoFinished();
}
}
}
//VideoPlayerController이용하기 위한 함수
void _initVideoPlayer() async {
await _videoPlayerController.initialize();
_videoPlayerController.play();
setState(() {});
//VideoPlayerController를 어떻게 처리해줄 지 지정하는 listener
_videoPlayerController.addListener(_onVideoChange);
}
@override
//VideoPlayerController이용하기 위한 함수1
void initState() {
super.initState();
_initVideoPlayer();
}
//VideoPlayerController이용하기 위한 함수2, 보고 있지 않을 때도 캐쉬 살려두기 위함
@override
void dispose() {
_videoPlayerController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
Positioned.fill(
child: _videoPlayerController.value.isInitialized
? VideoPlayer(_videoPlayerController)
: Container(
color: Colors.black,
),
),
],
);
}
}
import 'package:flutter/material.dart';
import 'package:tiktok_clone/features/videos/widgets/video_post.dart';
class VideoTimelineScreen extends StatefulWidget {
const VideoTimelineScreen({super.key});
@override
State<VideoTimelineScreen> createState() => _VideoTimelineScreenState();
}
class _VideoTimelineScreenState extends State<VideoTimelineScreen> {
int _itemCount = 4;
//스크린 넘어갈 때 느려지는 효과 없애는 함수:Pageview.builder를 컨트롤 하는 파라미터
final PageController _pageController = PageController();
//_pageController관련 파라메터
final Duration _scrollDuration = const Duration(milliseconds: 250);
final Curve _scrollCurve = Curves.linear;
void _onPageChanged(int page) {
//스크린 넘어갈 때 느려지는 효과 없애는 함수
//curve:애니메이션의 종류
_pageController.animateToPage(
page,
duration: _scrollDuration,
curve: _scrollCurve,
);
if (page == _itemCount - 1) {
//페이지 무한으로 증식하게 해주는 함수
_itemCount = _itemCount + 4;
setState(() {});
}
}
// 비디오가 끝나면 어떻게 처리할지의 함수
void _onVideoFinished() {
_pageController.nextPage(
duration: _scrollDuration,
curve: _scrollCurve,
);
}
// 비디오가 끝나면 어떻게 처리할지의 함수,보고 있지 않을 때도 캐쉬 살려두기 위함
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
// 유용한 새 위젯
return PageView.builder(
//스크린 넘어갈 때 느려지는 효과 없애는 파라미터
controller: _pageController,
// 자석 같이 화면이 딱딱 달라붙는 효과 property
//pageSnapping: false,
// 위로 스크롤 할 수 있는 property
scrollDirection: Axis.vertical,
//페이지 무한으로 증식하게 해주는 파라미터
onPageChanged: _onPageChanged,
itemCount: _itemCount,
itemBuilder: (context, index) => VideoPost(
onVideoFinished:
_onVideoFinished), //VideoPost로 넘기고 onVideoFinished 처리(다음 비디오로 넘어가기)
//->VideoPost의 statefulwidget으로 넘겨줌(state한테가 아니라)
);
}
}
7.4 VisibilityDetector
한쪽에서만 영상 재생되도록 해주는 설정


//페이지 무한으로 증식하게 해주는 파라미터
onPageChanged: _onPageChanged,
itemCount: _itemCount,
itemBuilder: (context, index) =>
-------------------
//VideoPost로 넘기고 onVideoFinished 처리(다음 비디오로 넘어가기)->VideoPost의 statefulwidget으로 넘겨줌(state한테가 아니라)
//index로 어느 페이지 보고 있는지 체크
VideoPost(onVideoFinished: _onVideoFinished, index: index),
);
}
}
-------------------

_videoPlayerController.dispose();
super.dispose();
}
------------------
// 비디오가 보여지는 영역을 계산하고 한쪽에서만 영상 재생되도록 해주는 파라메터
void _onVisibilityChanged(VisibilityInfo info) {
if (info.visibleFraction == 1 && !_videoPlayerController.value.isPlaying) {
_videoPlayerController.play();
}
}
------------------
@override
Widget build(BuildContext context) {
------------------
// 비디오가 보여지는 영역을 계산하고 한쪽에서만 영상 재생되도록 해주는 위젯
return VisibilityDetector(
key: Key("${widget.index}"),
onVisibilityChanged: _onVisibilityChanged,
------------------
child: Stack(
children: [
Positioned.fill(

_videoPlayerController.play();
}
}
-----------------
//토글하면 화면 멈추기 파라메터
void _onTogglePause() {
if (_videoPlayerController.value.isPlaying) {
_videoPlayerController.pause();
} else {
_videoPlayerController.play();
}
}
-----------------
@override
Widget build(BuildContext context) {
child: Stack(
children: [
Positioned.fill(
child: _videoPlayerController.value.isInitialized
? VideoPlayer(_videoPlayerController)
: Container(
color: Colors.black,
),
),
---------------
//토글하면 화면 멈추기
Positioned.fill(
child: GestureDetector(
onTap: _onTogglePause,
),
---------------

//토글하면 화면 멈추기
Positioned.fill(
child: GestureDetector(
onTap: _onTogglePause,
),
),
-------------------
const Positioned.fill(
//아이콘을 GestureDetector로 또 감싸는게 아닌 IgnorePointer로 _onTogglePause 이벤트리스너 듣게 하기
child: IgnorePointer(
child: Center(
child: FaIcon(
FontAwesomeIcons.play,
color: Colors.white,
size: Sizes.size52,
),
),
),
-------------------

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 {
//onVideoFinished 처리해주기 위한 property,statefulWideget은 여기 있는데 작업은 state에서 해줄 필요
final Function onVideoFinished;
//index로 어느 페이지 보고 있는지 체크
final int index;
//onVideoFinished 처리해주기 위한 property의 costructor->이거는 State<VideoPost>로 접근
//위젯 자체에 접근하게 해주는 것 밑에 만들어줄 필요,statefulWideget은 여기 있는데 작업은 state에서 해줄 필요
//index로 어느 페이지 보고 있는지 체크
const VideoPost({
super.key,
required this.onVideoFinished,
required this.index,
});
@override
State<VideoPost> createState() => _VideoPostState();
}
//animation을 커스터마이즈하는 하기 위해 클래스에 with이하 추가
class _VideoPostState extends State<VideoPost>
with SingleTickerProviderStateMixin {
//VideoPlayerController이용하기 위한 함수
final VideoPlayerController _videoPlayerController =
VideoPlayerController.asset("assets/videos/video.mp4");
final Duration _animationDuration = const Duration(milliseconds: 200);
//animation을 커스터마이즈하는 함수
late final AnimationController _animationController;
bool _isPaused = false;
//VideoPlayerController를 어떻게 처리해줄 지 지정하는 listener에 넣어줄 파라메터
//_videoPlayerController.value.duration(비디오길이)가 10초이고 _videoPlayerController.value.position(현재영상내의위치)이 10초이면 영상 끝냄처리
void _onVideoChange() {
if (_videoPlayerController.value.isInitialized) {
if (_videoPlayerController.value.duration ==
_videoPlayerController.value.position) {
//위젯 자체에 접근하게 해주는 것,statefulWideget은 위 있는데 작업은 state에서 해줄 필요
widget.onVideoFinished();
}
}
}
//VideoPlayerController이용하기 위한 함수
void _initVideoPlayer() async {
await _videoPlayerController.initialize();
//autoplay
// _videoPlayerController.play();
//VideoPlayerController를 어떻게 처리해줄 지 지정하는 listener
_videoPlayerController.addListener(_onVideoChange);
setState(() {});
}
@override
//VideoPlayerController이용하기 위한 함수1
void initState() {
super.initState();
_initVideoPlayer();
//animation을 커스터마이즈하는 parameter
_animationController = AnimationController(
vsync: this,
lowerBound: 1.0,
upperBound: 1.5,
value: 1.5, //디폴트 표시
duration: _animationDuration,
);
// 위의 중간값을 애니메이션 처리해주는(밑에 build 매소드가 중간값 읽기위한) 이벤트 리스너1
_animationController.addListener(() {
setState(() {});
});
}
//VideoPlayerController이용하기 위한 함수2, 보고 있지 않을 때도 캐쉬 살려두기 위함
@override
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();
//정지 누르면 재생아이콘 lowerBound: 1.0된다.
_animationController.reverse();
} else {
_videoPlayerController.play();
//플레이 누르면 재생아이콘 upperBound: 1.5,된다.
_animationController.forward();
}
setState(() {
_isPaused = !_isPaused;
});
}
@override
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,
),
),
Positioned.fill(
//아이콘을 GestureDetector로 또 감싸는게 아닌 IgnorePointer로 _onTogglePause 이벤트리스너 듣게 하기
child: IgnorePointer(
child: Center(
//animation을 커스터마이즈하는 parameter 2
// child: AnimatedBuilder(
// animation: _animationController,
// builder: (context, child) {
// return Transform.scale(
// scale: _animationController.value,
// child: child,
// );
// },
//animation을 커스터마이즈하는 parameter 1
child: Transform.scale(
scale: _animationController.value,
child: AnimatedOpacity(
opacity: _isPaused ? 1 : 0,
duration: _animationDuration,
child: const FaIcon(
FontAwesomeIcons.play,
color: Colors.white,
size: Sizes.size52,
),
),
),
),
),
),
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:tiktok_clone/features/videos/widgets/video_post.dart';
class VideoTimelineScreen extends StatefulWidget {
const VideoTimelineScreen({super.key});
@override
State<VideoTimelineScreen> createState() => _VideoTimelineScreenState();
}
class _VideoTimelineScreenState extends State<VideoTimelineScreen> {
int _itemCount = 4;
//스크린 넘어갈 때 느려지는 효과 없애는 함수:Pageview.builder를 컨트롤 하는 파라미터
final PageController _pageController = PageController();
//_pageController관련 파라메터
final Duration _scrollDuration = const Duration(milliseconds: 250);
final Curve _scrollCurve = Curves.linear;
void _onPageChanged(int page) {
//스크린 넘어갈 때 느려지는 효과 없애는 함수
//curve:애니메이션의 종류
_pageController.animateToPage(
page,
duration: _scrollDuration,
curve: _scrollCurve,
);
if (page == _itemCount - 1) {
//페이지 무한으로 증식하게 해주는 함수
_itemCount = _itemCount + 4;
setState(() {});
}
}
// 비디오가 끝나면 어떻게 처리할지의 함수
void _onVideoFinished() {
_pageController.nextPage(
duration: _scrollDuration,
curve: _scrollCurve,
);
}
// 비디오가 끝나면 어떻게 처리할지의 함수,보고 있지 않을 때도 캐쉬 살려두기 위함
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
// 유용한 새 위젯
return PageView.builder(
//스크린 넘어갈 때 느려지는 효과 없애는 파라미터
controller: _pageController,
// 자석 같이 화면이 딱딱 달라붙는 효과 property
//pageSnapping: false,
// 위로 스크롤 할 수 있는 property
scrollDirection: Axis.vertical,
//페이지 무한으로 증식하게 해주는 파라미터
onPageChanged: _onPageChanged,
itemCount: _itemCount,
itemBuilder: (context, index) =>
//VideoPost로 넘기고 onVideoFinished 처리(다음 비디오로 넘어가기)->VideoPost의 statefulwidget으로 넘겨줌(state한테가 아니라)
//index로 어느 페이지 보고 있는지 체크
VideoPost(onVideoFinished: _onVideoFinished, index: index),
);
}
}728x90
반응형
'Programing > Flutter' 카테고리의 다른 글
Comments