Youtube 像颤动的全屏按钮 [英] Youtube like fullscreen button on flutter

查看:12
本文介绍了Youtube 像颤动的全屏按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在疯狂地尝试实现一个类似 Youtube 的全屏按钮,我在 OrientationBuilder 中有我的小部件树,逻辑应该遵循这个方案:

如果方向被用户锁定:全屏按钮应将方向从纵向更改为横向,如果在全屏时,按钮应更改为纵向这部分没有问题,我只是调用正确的 SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);SystemChrome.setPreferredOrientations([DeviceOrientation.portrait]);一切正常

如果方向未被用户锁定:这就是一切变得棘手的地方……如果纵向并且按下全屏按钮SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]); 应该被调用,但是,如果用户将手机旋转到横向,然后再回到纵向,方向应该恢复到原来的纵向(勾选youtube)在全屏时也会发生同样的情况,按钮切换到纵向,然后如果我将手机移回纵向,然后再回到横向,应用程序应该再次旋转.我唯一完成的事情是在 iOS 上获得正确的功能,在布局构建器上,我在返回 OrientationBuilder 构建器方法之前将首选方向重置为portrait、landscapeLeft、landscapeRight",但在 Android 中这会导致应用程序要以当前方向重建,但在 iOS 中它会一直保持到来回旋转,知道吗?

解决方案

我在我的应用程序上禁用全屏模式时遇到了类似的问题.为了启用全屏,我使用 SystemChrome.setPreferredOrientations() 强制应用处于横向.然后我通过将首选方向设置为纵向来禁用全屏.

void _enableFullscreen(bool fullscreen) {isFullscreen = 全屏;如果(全屏){//强制全屏横向SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft,DeviceOrientation.landscapeRight,]);} 别的 {//强制人像SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp,DeviceOrientation.portraitDown,]);}}

应用使用 OrientationBuilder 检测设备的方向.

OrientationBuilder(builder: (context,orientation) {debugPrint('设备方向:$orientation');isFullscreen = 方向 == Orientation.landscape;返回是全屏///横向布局?容器()///纵向布局: 柱子();})

我在这里遇到的问题是,在设置首选方向后,小部件不会根据设备的方向(即自动旋转)重建.为了解决这个问题,我在 setPreferredOrientations() 上设置了一个空列表,以指示 Flutter 应用再次按照

I’m becoming crazy trying to implement a Youtube-like fullscreen button, I have my widget tree inside an OrientationBuilder and the logic should follow this scheme:

If the orientation is locked by user: Fullscreen button should change the orientation from portrait to landscape, if in full screen the button should change to portrait this part is not a problem, I just call the correct SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]); or SystemChrome.setPreferredOrientations([DeviceOrientation.portrait]); and everything works ad expected

If the orientation is NOT locked by user: This is where everything becomes tricky… If in portrait and the fullscreen button is pressed SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]); should be called, but, if the user rotate the phone to landscape, and then back to portrait the orientation should be restored to the original portrait (check on youtube) the same should happen in fullscreen, the button swap to portrait, then if I move the phone back to portrait and then back to landscape, the app should rotate again. The only things that I have accomplished is to get the correct functionality on iOS, on the layout builder, I reset the preferred Orientation to "portrait, landscapeLeft, landscapeRight" just before the return of the OrientationBuilder builder method, but in Android this cause the Application to be rebuilt with the current orientation, but in iOS it stays until a back and forth rotation, any idea?

解决方案

I encountered a similar issue on disabling fullscreen mode on my app. To enable fullscreen, I force the app to be on landscape by using SystemChrome.setPreferredOrientations(). I then disable fullscreen by setting the preferred orientation to portrait.

void _enableFullscreen(bool fullscreen) {
  isFullscreen = fullscreen;
  if (fullscreen) {
    // Force landscape orientation for fullscreen
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.landscapeLeft,
      DeviceOrientation.landscapeRight,
    ]);
  } else {
    // Force portrait
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
      DeviceOrientation.portraitDown,
    ]);
  }
}

The app detects the device's orientation using OrientationBuilder.

OrientationBuilder(builder: (context, orientation) {
  debugPrint('Device orientation: $orientation');
  isFullscreen = orientation == Orientation.landscape;
  return isFullscreen

      /// Landscape Layout
      ? Container()
       
      /// Portrait Layout
      : Column();
})

The issue that I encountered here was the widget doesn't rebuild base on the device's orientation (i.e. auto-rotate) after setting a preferred orientation. To solve this issue I set an empty list on setPreferredOrientations() to instruct the Flutter app to defer to the operating system default (orientation) again as mentioned in the docs.

Here's a complete sample. I'm using Flutter 2.5

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool isFullscreen = false;

  void _enableFullscreen(bool fullscreen) {
    isFullscreen = fullscreen;
    if (fullscreen) {
      // Force landscape orientation for fullscreen
      SystemChrome.setPreferredOrientations([
        DeviceOrientation.landscapeLeft,
        DeviceOrientation.landscapeRight,
      ]);
    } else {
      // Force portrait
      SystemChrome.setPreferredOrientations([
        DeviceOrientation.portraitUp,
        DeviceOrientation.portraitDown,
      ]);
      // Set preferred orientation to device default
      // Empty list causes the application to defer to the operating system default.
      // See: https://api.flutter.dev/flutter/services/SystemChrome/setPreferredOrientations.html
      SystemChrome.setPreferredOrientations([]);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: OrientationBuilder(builder: (context, orientation) {
        debugPrint('Device orientation: $orientation');
        isFullscreen = orientation == Orientation.landscape;
        return isFullscreen

            /// Landscape Layout
            ? Container(color: Colors.green)

            /// Portrait Layout
            : Column(
                children: [
                  Expanded(
                    flex: 1,
                    child: Container(color: Colors.green),
                  ),
                  Expanded(
                    flex: 3,
                    child: Container(color: Colors.lightBlueAccent),
                  )
                ],
              );
      }),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _enableFullscreen(!isFullscreen);
        },
        tooltip: 'Fullscreen',
        child: const Icon(Icons.fullscreen),
      ),
    );
  }
}

这篇关于Youtube 像颤动的全屏按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆