flutter video_player视频播放器的横竖屏切换

该博客介绍了如何在Flutter应用中实现在点击按钮后切换到横屏全屏显示视频,并在页面返回时自动恢复到竖屏显示。示例代码展示了使用SystemChrome.setPreferredOrientations方法设置屏幕方向,并在页面初始化和销毁时调用该方法进行切换。此外,还展示了视频播放控制的相关逻辑,包括监听视频播放状态、显示播放进度等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考

需要使用到的库:

import 'package:flutter/services.dart';
用到的方法:

//实现全屏功能代码,一般写在按钮或者初始化函数里
SystemChrome.setPreferredOrientations([
  DeviceOrientation.landscapeLeft, //全屏时旋转方向,左边
]);

//还原为竖屏功能代码,一般写在 dispose()方法中,页面返回时执行
 SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
]);
示例代码(部份):

import 'package:flutter/services.dart';
import 'package:video_player/video_player.dart';
import 'package:flutter/material.dart';

//跳转后的页面
class NewPlays extends StatefulWidget {
  //参数传递定义
  final VideoPlayerController controller;
  const NewPlays({Key key, this.controller}) : super(key: key);
  @override
  MyNewPlays createState() => MyNewPlays();
}

class MyNewPlays extends State<NewPlays> {

//初始化时直接向左边旋转全屏
  @override
  void initState() {
    super.initState();
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.landscapeLeft, //全屏时旋转方向,左边
    ]);
  }
  
   /*
             中间部份省略
   */

//页面销毁时执行还原操作
  @override
  void dispose() {
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
    ]);
    super.dispose();
  }
}

我自己的

import 'dart:async';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:video_player/video_player.dart';

import '../../router.dart';

//横屏界面
class MovieBigLandScape extends StatefulWidget {
  //参数传递定义
  final VideoPlayerController videoController;

  const MovieBigLandScape({Key? key, required this.videoController})
      : super(key: key);

  @override
  State<StatefulWidget> createState() => MovieBigLandScapeState();
}

class MovieBigLandScapeState extends State<MovieBigLandScape> {
  bool isPress = false;
  late Timer? isPressTimer;

  //获取当前视频播放的信息
  late VideoPlayerValue videoPlayerValue;

  //当前播放视频的总时长
  late Duration totalDuration;

  //当前播放视频的位置
  late Duration currentDuration;

  String tDuration = "0:00:00";
  String cDuration = "0:00:00";

  //当前视频是否缓存
  bool isBuffer = false;

  @override
  void initState() {
    isPressTimer = Timer(const Duration(), () {});
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.landscapeLeft, //全屏时旋转方向,左边
    ]);
    widget.videoController.addListener(() {
      mySetState(() {
        videoPlayerValue = widget.videoController.value;
        totalDuration = videoPlayerValue.duration;
        currentDuration = videoPlayerValue.position;
        tDuration = totalDuration.toString().substring(0, 7);
        cDuration = currentDuration.toString().substring(0, 7);
        isBuffer = videoPlayerValue.isBuffering;
      });
    });
    super.initState();
  }

  mySetState(callBack) {
    if (mounted) {
      setState(() {
        callBack();
      });
    }
  }

  @override
  void dispose() {
    if (isPressTimer != null) {
      isPressTimer?.cancel();
      isPressTimer = null;
    }
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
    ]);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Material(
      child: Stack(
        alignment: Alignment.center,
        children: [
          Stack(
            alignment: Alignment.bottomCenter,
            children: [
              Stack(
                alignment: Alignment.bottomCenter,
                children: [
                  GestureDetector(
                    onTap: () {
                      setState(() {
                        isPress = !isPress;
                      });
                      if (isPressTimer != null) {
                        isPressTimer?.cancel();
                        isPressTimer = null;
                      }
                      isPressTimer =
                          Timer(const Duration(milliseconds: 5000), () {
                        setState(() {
                          isPress = false;
                        });
                      });
                    },
                    child: Container(
                        color: Colors.black,
                        alignment: Alignment.topCenter,
                        child: AspectRatio(
                            aspectRatio:
                                widget.videoController.value.aspectRatio,
                            child: VideoPlayer(widget.videoController))),
                  ),
                  if (isPress)
                    Row(
                      children: [
                        GestureDetector(
                          onDoubleTap: () {
                            widget.videoController.value.isPlaying
                                ? widget.videoController.pause()
                                : widget.videoController.play();
                          },
                          onTap: () {
                            widget.videoController.value.isPlaying
                                ? widget.videoController.pause()
                                : widget.videoController.play();
                          },
                          child: Container(
                            padding: const EdgeInsets.only(bottom: 5),
                            child: Icon(
                              widget.videoController.value.isPlaying
                                  ? Icons.pause
                                  : Icons.play_arrow,
                              color: Colors.white,
                              size: 30,
                            ),
                          ),
                        ),
                        Expanded(
                            child: Container(
                          padding: const EdgeInsets.only(bottom: 5),
                          child: VideoProgressIndicator(
                            widget.videoController,
                            allowScrubbing: true,
                            colors: const VideoProgressColors(
                                backgroundColor: Colors.white24,
                                bufferedColor: Colors.white,
                                playedColor: Colors.pinkAccent),
                          ),
                        )),
                        Container(
                          margin: const EdgeInsets.only(left: 5),
                          child: Text(
                            "$cDuration/$tDuration",
                            style: const TextStyle(
                                color: Colors.white, fontSize: 9),
                          ),
                        ),
                        GestureDetector(
                          onTap: () {
                            MyRouter.pop(context);
                          },
                          child: Container(
                            padding: const EdgeInsets.only(bottom: 5),
                            child: const Icon(
                              Icons.play_arrow,
                              color: Colors.white,
                              size: 30,
                            ),
                          ),
                        ),
                      ],
                    ),
                ],
              ),
              if (!isPress)
                VideoProgressIndicator(
                  widget.videoController,
                  allowScrubbing: true,
                  colors: const VideoProgressColors(
                      backgroundColor: Colors.white24,
                      bufferedColor: Colors.white,
                      playedColor: Colors.pinkAccent),
                )
            ],
          ),
          if (isBuffer)
            const SizedBox(
              height: 30,
              width: 30,
              child: CircularProgressIndicator(
                backgroundColor: Colors.white,
              ),
            )
        ],
      ),
    );
  }
}

A:以下是一个简单的 Flutter video_player 视频播放器模板供参考: ```dart import 'package:flutter/material.dart'; import 'package:video_player/video_player.dart'; void main() => runApp(MyApp()); class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { VideoPlayerController _controller; @override void initState() { super.initState(); _controller = VideoPlayerController.asset('videos/sample.mp4') ..initialize().then((_) { setState(() {}); }); } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: Text('Video Player'), ), body: Center( child: _controller.value.initialized ? AspectRatio( aspectRatio: _controller.value.aspectRatio, child: VideoPlayer(_controller), ) : Container(), ), floatingActionButton: FloatingActionButton( onPressed: () { setState(() { _controller.value.isPlaying ? _controller.pause() : _controller.play(); }); }, child: Icon( _controller.value.isPlaying ? Icons.pause : Icons.play_arrow, ), ), ), ); } @override void dispose() { super.dispose(); _controller.dispose(); } } ``` 在本例中,我们使用 asset 目录下的示例视频文件来初始化 VideoPlayerController。在 initState() 生命周期中,我们调用 initialize() 方法来初始化该控制器,并在该过程完成后(即视频准备就绪后)调用 setState() 来更新 UI。在 build() 方法中,我们检查视频控制器的 initialized 属性,如果视频已经准备就绪,则使用 AspectRatio 和 VideoPlayer视频呈现为全屏可见的占位符。我们还在右下方添加了一个 FloatingActionButton,允许用户播放或暂停视频。最后,我们在 dispose() 生命周期中释放了视频控制器。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值