You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在youtube_player_flutter中检测全屏状态切换?

实现全屏切换时执行指定函数的方案

要在视频横竖屏切换(普通视图↔全屏)时触发自定义函数,你可以通过跟踪屏幕方向变化来实现。核心思路是记录上一次的屏幕方向,当方向发生改变时,判断是进入还是退出全屏,然后执行对应的逻辑。

修改后的完整代码

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
import 'package:mentors/models/video_model.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';

class VideoPlayer extends StatefulWidget {
  final VideoModel videoModel;

  const VideoPlayer({super.key, required this.videoModel});

  @override
  State<VideoPlayer> createState() => _VideoPlayerState();
}

class _VideoPlayerState extends State<VideoPlayer> {
  YoutubePlayerController? _controller;
  Orientation? _previousOrientation; // 记录上一次的屏幕方向

  @override
  void initState() {
    super.initState();
    _controller = YoutubePlayerController(
      initialVideoId: widget.videoModel.id,
      flags: const YoutubePlayerFlags(
        mute: false,
        autoPlay: true,
      ),
    );
    // 初始化时获取当前方向
    _previousOrientation = MediaQuery.of(context).orientation;
  }

  @override
  void dispose() {
    _controller?.dispose(); // 释放控制器资源
    // 恢复状态栏
    SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
        overlays: SystemUiOverlay.values);
    super.dispose();
  }

  // 进入全屏时执行的函数
  void _onEnterFullscreen() {
    print('切换到全屏模式');
    // 隐藏状态栏
    SystemChrome.setEnabledSystemUIMode(SystemUiMode.leanBack);
    // 这里可以添加你的自定义逻辑,比如暂停其他音频、调整页面状态等
  }

  // 退出全屏时执行的函数
  void _onExitFullscreen() {
    print('切换回普通视图');
    // 恢复状态栏
    SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual,
        overlays: SystemUiOverlay.values);
    // 这里可以添加你的自定义逻辑,比如恢复页面布局、继续其他操作等
  }

  @override
  Widget build(BuildContext context) {
    return OrientationBuilder(
        builder: (BuildContext context, Orientation orientation) {
      // 检测方向变化并触发对应函数
      if (_previousOrientation != null && _previousOrientation != orientation) {
        if (_previousOrientation == Orientation.portrait && orientation == Orientation.landscape) {
          _onEnterFullscreen();
        } else if (_previousOrientation == Orientation.landscape && orientation == Orientation.portrait) {
          _onExitFullscreen();
        }
        // 更新上一次的方向
        setState(() {
          _previousOrientation = orientation;
        });
      }

      if (orientation == Orientation.landscape) {
        return Scaffold(
            backgroundColor: Colors.black,
            body: Align(
              alignment: Alignment.center,
              child: FittedBox(
                fit: BoxFit.contain,
                child: YoutubePlayer(
                  controller: _controller!,
                  showVideoProgressIndicator: true,
                  onReady: () {},
                ),
              ),
            ));
      } else {
        return Scaffold(
          backgroundColor: Colors.white,
          body: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Container(
                color: Colors.black,
                height: 40,
              ),
              YoutubePlayer(
                controller: _controller!,
                showVideoProgressIndicator: true,
                onReady: () {},
              ),
              Expanded(
                child: Padding(
                  padding: const EdgeInsets.all(10),
                  child: SingleChildScrollView(
                    child: Column(
                      mainAxisSize: MainAxisSize.max,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text(
                          widget.videoModel.title,
                          style: const TextStyle(
                            color: Colors.black,
                            fontSize: 18.0,
                            fontWeight: FontWeight.w600,
                          ),
                        ),
                        Text(
                          DateFormat("dd MMM yyyy") // 修正原代码日期格式错误
                              .format(widget.videoModel.publishedAt),
                          style: const TextStyle(
                            color: Colors.grey,
                            fontSize: 14.0,
                          ),
                        ),
                        const Text(
                          "Description",
                          style: TextStyle(
                            color: Colors.black,
                            fontSize: 18.0,
                            fontWeight: FontWeight.w600,
                          ),
                        ),
                        Text(
                          widget.videoModel.description,
                          style: const TextStyle(
                            color: Colors.black,
                            fontSize: 14.0,
                            fontWeight: FontWeight.w500,
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              )
            ],
          ),
        );
      }
    });
  }
}

关键修改点说明

  1. 添加方向跟踪变量:_previousOrientation用来记录上一次的屏幕方向,避免初始加载时误触发回调。
  2. 定义切换回调函数:_onEnterFullscreen和_onExitFullscreen分别处理进入/退出全屏的逻辑,你可以在里面添加任何自定义操作。
  3. 方向变化检测:在OrientationBuilder中对比当前方向和上一次的方向,判断切换类型并触发对应函数。
  4. 代码优化:把原代码中分散的SystemChrome设置整合到回调函数里,逻辑更集中;同时修正了日期格式的拼写错误(yyyy而非yyy)。

内容的提问来源于stack exchange,提问作者Nehal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 04:27:15