如何判断当前PageView是否完全消失,下一个完全出现
How to check whether the current PageView totally disappears and the next one totally appears
我正在用Fluter开发一个APP。在 APP 中有一个 PageView 列表,每个 PageView 都会在出现时加载并播放视频。任何 PageView 在消失时都会停止播放视频。现在我有一个问题。当我在PageView之间慢慢滑动的时候,会同时出现两个PageView。每个 PageView 都显示为一个部分。但是这两个 PageView 都在播放视频。我想知道我是否可以检查当前的PageView是否完全消失,然后停止播放视频。当下一个 PageView 完全显示时,它开始播放视频。所以它不会同时在两个 PageView 中播放视频。谁能帮帮我?
import 'package:video_player/video_player.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MultiplePage(),
);
}
}
class MultiplePage extends StatefulWidget {
@override
_MultiplePageState createState() => _MultiplePageState();
}
class _MultiplePageState extends State<MultiplePage> {
PageController _controller;
void scrollListener() {
if (_controller.page == _controller.page.roundToDouble()) {
print(_controller.page);
}
}
@override
void initState() {
super.initState();
_controller = PageController()..addListener(scrollListener);
}
@override
Widget build(BuildContext context) {
return PageView.builder(
controller: _controller,
scrollDirection: Axis.vertical,
itemBuilder: (context, position) {
return VideoApp();
},
);
}
}
class VideoApp extends StatefulWidget {
@override
_VideoAppState createState() => _VideoAppState();
}
class _VideoAppState extends State<VideoApp> {
VideoPlayerController _controller;
@override
void initState() {
super.initState();
_controller = VideoPlayerController.network(
'http://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4')
..initialize().then((_) {
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
setState(() {
_controller.play();
});
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Video Demo',
home: Scaffold(
body: Center(
child: _controller.value.initialized
? AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
)
: Container(),
),
),
);
}
@override
void dispose() {
super.dispose();
_controller.pause();
_controller.dispose();
}
}
使用 PageController 检查页面是否完全翻动。
import 'package:video_player/video_player.dart';
import 'package:flutter/material.dart';
import 'package:sprintf/sprintf.dart';
import 'package:preload_page_view/preload_page_view.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MultiplePage(),
);
}
}
class MultiplePage extends StatefulWidget {
@override
_MultiplePageState createState() => _MultiplePageState();
}
class _MultiplePageState extends State<MultiplePage> {
PreloadPageController _controller;
int current = 0;
bool isOnPageTurning = false;
void scrollListener() {
if (isOnPageTurning &&
_controller.page == _controller.page.roundToDouble()) {
setState(() {
current = _controller.page.toInt();
isOnPageTurning = false;
});
} else if (!isOnPageTurning && current.toDouble() != _controller.page) {
if ((current.toDouble() - _controller.page).abs() > 0.1) {
setState(() {
isOnPageTurning = true;
});
}
}
}
@override
void initState() {
super.initState();
_controller = PreloadPageController();
_controller.addListener(scrollListener);
}
@override
Widget build(BuildContext context) {
return PreloadPageView.builder(
controller: _controller,
scrollDirection: Axis.vertical,
preloadPagesCount: 3,
itemBuilder: (context, pageIndex) {
return VideoApp(
pageIndex: pageIndex,
currentPageIndex: current,
isPaused: isOnPageTurning,
);
},
);
}
}
class VideoApp extends StatefulWidget {
VideoApp({
this.pageIndex,
this.currentPageIndex,
this.isPaused,
});
final int pageIndex;
final int currentPageIndex;
final bool isPaused;
@override
_VideoAppState createState() => _VideoAppState();
}
class _VideoAppState extends State<VideoApp> {
VideoPlayerController _controller;
bool initialized = false;
@override
void initState() {
super.initState();
print(sprintf("init: %d", [widget.pageIndex]));
_controller = VideoPlayerController.network(
"http://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4")
..initialize().then((_) {
setState(() {
_controller.setLooping(true);
initialized = true;
});
});
}
@override
Widget build(BuildContext context) {
if (widget.pageIndex == widget.currentPageIndex &&
!widget.isPaused &&
initialized) {
_controller.play();
} else {
_controller.pause();
}
return MaterialApp(
title: 'Video Demo',
home: Scaffold(
body: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border.all(
color: Colors.blueAccent,
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('is paused: ${widget.isPaused.toString()}'),
Text('currentPageIndex: ${widget.currentPageIndex.toString()}'),
Text('pageIndex: ${widget.pageIndex.toString()}'),
_controller.value.initialized
? AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
)
: Container(
decoration: BoxDecoration(color: Colors.black),
),
],
),
),
),
);
}
@override
void dispose() {
print(sprintf("dispose: %d", [widget.pageIndex]));
super.dispose();
_controller.dispose();
}
}
...
如果其他人正在搜索相同的答案,使用的包是:
video_player: ^0.10.1+3
http: ^0.12.0+2
sprintf: ^4.0.2
preload_page_view: ^0.1.4
您实际上不需要手动停止消失页面上的视频。
默认情况下,PageView
会在页面完全滚出时自动处理该页面。当您开始滚动时,它会重新创建 Page
。
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Video Player Demo',
home: MainPage(),
);
}
}
class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Demo")),
body: PageView(
children: <Widget>[
Page1(),
Page1(),
Page1(),
],
),
);
}
}
class Page1 extends StatefulWidget {
Page1({Key key}) : super(key: key);
@override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
VideoPlayerController _controller;
Future<void> _initializeVideoPlayerFuture;
@override
void initState() {
_controller = VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
);
_initializeVideoPlayerFuture = _controller.initialize();
_controller.setLooping(true);
_controller.play();
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Center(
child: FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
} else {
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
);
}
},
),
);
}
}
我正在用Fluter开发一个APP。在 APP 中有一个 PageView 列表,每个 PageView 都会在出现时加载并播放视频。任何 PageView 在消失时都会停止播放视频。现在我有一个问题。当我在PageView之间慢慢滑动的时候,会同时出现两个PageView。每个 PageView 都显示为一个部分。但是这两个 PageView 都在播放视频。我想知道我是否可以检查当前的PageView是否完全消失,然后停止播放视频。当下一个 PageView 完全显示时,它开始播放视频。所以它不会同时在两个 PageView 中播放视频。谁能帮帮我?
import 'package:video_player/video_player.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MultiplePage(),
);
}
}
class MultiplePage extends StatefulWidget {
@override
_MultiplePageState createState() => _MultiplePageState();
}
class _MultiplePageState extends State<MultiplePage> {
PageController _controller;
void scrollListener() {
if (_controller.page == _controller.page.roundToDouble()) {
print(_controller.page);
}
}
@override
void initState() {
super.initState();
_controller = PageController()..addListener(scrollListener);
}
@override
Widget build(BuildContext context) {
return PageView.builder(
controller: _controller,
scrollDirection: Axis.vertical,
itemBuilder: (context, position) {
return VideoApp();
},
);
}
}
class VideoApp extends StatefulWidget {
@override
_VideoAppState createState() => _VideoAppState();
}
class _VideoAppState extends State<VideoApp> {
VideoPlayerController _controller;
@override
void initState() {
super.initState();
_controller = VideoPlayerController.network(
'http://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4')
..initialize().then((_) {
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
setState(() {
_controller.play();
});
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Video Demo',
home: Scaffold(
body: Center(
child: _controller.value.initialized
? AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
)
: Container(),
),
),
);
}
@override
void dispose() {
super.dispose();
_controller.pause();
_controller.dispose();
}
}
使用 PageController 检查页面是否完全翻动。
import 'package:video_player/video_player.dart';
import 'package:flutter/material.dart';
import 'package:sprintf/sprintf.dart';
import 'package:preload_page_view/preload_page_view.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MultiplePage(),
);
}
}
class MultiplePage extends StatefulWidget {
@override
_MultiplePageState createState() => _MultiplePageState();
}
class _MultiplePageState extends State<MultiplePage> {
PreloadPageController _controller;
int current = 0;
bool isOnPageTurning = false;
void scrollListener() {
if (isOnPageTurning &&
_controller.page == _controller.page.roundToDouble()) {
setState(() {
current = _controller.page.toInt();
isOnPageTurning = false;
});
} else if (!isOnPageTurning && current.toDouble() != _controller.page) {
if ((current.toDouble() - _controller.page).abs() > 0.1) {
setState(() {
isOnPageTurning = true;
});
}
}
}
@override
void initState() {
super.initState();
_controller = PreloadPageController();
_controller.addListener(scrollListener);
}
@override
Widget build(BuildContext context) {
return PreloadPageView.builder(
controller: _controller,
scrollDirection: Axis.vertical,
preloadPagesCount: 3,
itemBuilder: (context, pageIndex) {
return VideoApp(
pageIndex: pageIndex,
currentPageIndex: current,
isPaused: isOnPageTurning,
);
},
);
}
}
class VideoApp extends StatefulWidget {
VideoApp({
this.pageIndex,
this.currentPageIndex,
this.isPaused,
});
final int pageIndex;
final int currentPageIndex;
final bool isPaused;
@override
_VideoAppState createState() => _VideoAppState();
}
class _VideoAppState extends State<VideoApp> {
VideoPlayerController _controller;
bool initialized = false;
@override
void initState() {
super.initState();
print(sprintf("init: %d", [widget.pageIndex]));
_controller = VideoPlayerController.network(
"http://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4")
..initialize().then((_) {
setState(() {
_controller.setLooping(true);
initialized = true;
});
});
}
@override
Widget build(BuildContext context) {
if (widget.pageIndex == widget.currentPageIndex &&
!widget.isPaused &&
initialized) {
_controller.play();
} else {
_controller.pause();
}
return MaterialApp(
title: 'Video Demo',
home: Scaffold(
body: Container(
alignment: Alignment.center,
decoration: BoxDecoration(
border: Border.all(
color: Colors.blueAccent,
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('is paused: ${widget.isPaused.toString()}'),
Text('currentPageIndex: ${widget.currentPageIndex.toString()}'),
Text('pageIndex: ${widget.pageIndex.toString()}'),
_controller.value.initialized
? AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
)
: Container(
decoration: BoxDecoration(color: Colors.black),
),
],
),
),
),
);
}
@override
void dispose() {
print(sprintf("dispose: %d", [widget.pageIndex]));
super.dispose();
_controller.dispose();
}
}
...
如果其他人正在搜索相同的答案,使用的包是:
video_player: ^0.10.1+3
http: ^0.12.0+2
sprintf: ^4.0.2
preload_page_view: ^0.1.4
您实际上不需要手动停止消失页面上的视频。
默认情况下,PageView
会在页面完全滚出时自动处理该页面。当您开始滚动时,它会重新创建 Page
。
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Video Player Demo',
home: MainPage(),
);
}
}
class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Demo")),
body: PageView(
children: <Widget>[
Page1(),
Page1(),
Page1(),
],
),
);
}
}
class Page1 extends StatefulWidget {
Page1({Key key}) : super(key: key);
@override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
VideoPlayerController _controller;
Future<void> _initializeVideoPlayerFuture;
@override
void initState() {
_controller = VideoPlayerController.network(
'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4',
);
_initializeVideoPlayerFuture = _controller.initialize();
_controller.setLooping(true);
_controller.play();
super.initState();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Center(
child: FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
} else {
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
);
}
},
),
);
}
}