android - 从一个页面导航到另一个页面时如何暂停抖动视频(video_player 插件)

标签 android ios dart flutter

我正在使用 flutter video_player( https://pub.dartlang.org/packages/video_player ) 插件来播放视频。但是当我从一页导航到另一页时,视频仍在播放。从任何其他应用程序播放音乐时我遇到了同样的问题(例如:在播放 flutter 视频时从通知播放音乐)。我怎样才能暂停它?

最佳答案

编辑: 第二个选项: 所以我想出了另一个解决方案。 VisibilityDetector 是一个 `Widget',它可以包装任何其他 Widget,并在该 widget 的可见区域发生变化时发出通知。

VisibilityDetector(
   key: Key("unique key"),
   onVisibilityChanged: (VisibilityInfo info) {
       debugPrint("${info.visibleFraction} of my widget is visible");
       if(info.visibleFraction == 0){
           videoPlayerController.pause();
       }
       else{
           videoPlayerController.play();
       }
   },
   child: VideoPlayer());
)

第一个选项: 通过使用 RouteObserverRouteAware,只要另一个屏幕被推到它上面,或者它弹回顶部,您的小部件就会收到通知。

首先,您需要将 RouteObserver 添加到 MaterialApp 或您的 Navigator

RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      navigatorObservers: [routeObserver], //HERE
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

然后您必须将 RouteAware 混合添加到您的小部件,并将其订阅到 RouteObserver

class VideoPlayerItem extends StatefulWidget {
  final File file;

  VideoPlayerItem(this.file);

  @override
  _VideoPlayerItemState createState() => _VideoPlayerItemState();
}

class _VideoPlayerItemState extends State<VideoPlayerItem> with RouteAware {

  VideoPlayerController _videoPlayerController;

  @override
  void initState() {
    super.initState();
    _videoPlayerController = VideoPlayerController.file(widget.file);
    _videoPlayerController.initialize().then((_) {
      if (mounted) {
        setState(() {});
        _videoPlayerController.play();
      }
    });
  }

  @override
  void didChangeDependencies() {
    routeObserver.subscribe(this, ModalRoute.of(context));//Subscribe it here
    super.didChangeDependencies();
  }

  /// Called when the current route has been popped off.
  @override
  void didPop() {
    print("didPop");
    super.didPop();
  }

  /// Called when the top route has been popped off, and the current route
  /// shows up.
  @override
  void didPopNext() {
    print("didPopNext");
    _videoPlayerController.play();
    super.didPopNext();
  }

  /// Called when the current route has been pushed.
  @override
  void didPush() { 
    print("didPush");
    super.didPush();
  }

  /// Called when a new route has been pushed, and the current route is no
  /// longer visible.
  @override
  void didPushNext() {
    print("didPushNext");
    _videoPlayerController.pause();
    super.didPushNext();
  }


  @override
  Widget build(BuildContext context) {
    return _videoPlayerController?.value?.initialized ?? false
        ? AspectRatio(
            aspectRatio: _videoPlayerController.value.aspectRatio,
            child: VideoPlayer(_videoPlayerController),
          )
        : Container();
  }

  @override
  void dispose() {
    routeObserver.unsubscribe(this); //Don't forget to unsubscribe it!!!!!!
    super.dispose();
    _videoPlayerController.dispose();
  }
}

关于android - 从一个页面导航到另一个页面时如何暂停抖动视频(video_player 插件),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54692450/

相关文章:

android - 将 LinearLayout 中的 View 内容居中

java - 无法解析 FragmentPagerAdapter 的父类(super class)

database - Android:是否可以访问与我的应用程序 bundle 在一起的 sqlite 文件?

ios - 如何存储数据以备将来在 iOS 应用程序中使用

ios - 我可以开发一个ipad应用程序并将其通过链接分发给一个客户端吗?

android - Flutter CustomPaint 不会重绘

firebase-realtime-database - 如何在 Flutter 的 FirebaseDatabase 插件中使用 ServerValue

dart - 如何让 Geolocation API 在 Dartium 中工作?

android - BOOT_COMPLETED 的 BroadcastReceiver 太慢

ios - 在iOS中将日期从字符串转换为NSDate