Flutter双屏支持插件dual_screen的使用

发布于 1周前 作者 gougou168 来自 Flutter

Flutter双屏支持插件dual_screen的使用

Flutter Dual Screen

Flutter Dual Screen 插件包含微软为简化折叠屏和双屏设备开发提供的工具。虽然该插件可以在任何平台上工作,但目前只有Android平台拥有实际的折叠屏和双屏设备。

Flutter已经通过MediaQuery Display Features提供了对折叠屏和双屏设备的支持。除了这些功能之外,此插件还提供了:

  • TwoPane Widget:依赖于来自MediaQuery的显示特性。
  • 访问铰链角度传感器数据:出于性能考虑,这部分数据未包含在MediaQuery中。

TwoPane Widget

TwoPane布局具有两个子窗格,可以并排、上下堆叠显示,或仅优先显示一个窗格。两个窗格小部件的相对大小可以按比例调整;在双屏设备上,边界会固定到铰链区域。

TwoPane API

class TwoPane {
  const TwoPane({
    Widget startPane,
    Widget endPane,
    double paneProportion,
    TwoPanePriority panePriority,
    Axis direction,
    TextDirection? textDirection,
    VerticalDirection verticalDirection,
    EdgeInsets padding,
    Set<TwoPaneAllowedOverrides> allowedOverrides,
  });
}
  • startPane - 开始窗格,在左到右布局中位于左侧,在上到下布局中位于顶部。如果panePrioritystart且没有铰链,这是唯一可见的窗格。
  • endPane - 结束窗格,在左到右布局中位于右侧,在上到下布局中位于底部。如果panePriorityend且没有铰链,这是唯一可见的窗格。
  • paneProportion - 屏幕被开始窗格占用的比例。结束窗格占据其余空间。0.5将使两个窗格相等。对于带有铰链的显示器,此属性被忽略,每个窗格占据一个屏幕。
  • panePriority - 显示开始窗格、结束窗格或两者。对于带有铰链的显示器,此属性被忽略,both窗格可见。
  • direction - 窗格是垂直还是水平堆叠,类似于Flex方向。对于带有铰链的显示器,此属性被忽略,方向为垂直铰链时为vertical,水平铰链时为horizontal
  • textDirection - 当窗格水平排列时,这决定了哪个窗格在左边。与Flex的textDirection行为相同。
  • verticalDirection - 当窗格垂直排列时,这决定了哪个窗格在顶部。与Flex的verticalDirection行为相同。
  • padding - TwoPane与屏幕边缘之间的填充。如果有间距,padding用于正确对齐两个窗格以适应铰链。
  • allowedOverrides - 当找到分离显示特性时,允许TwoPane覆盖的参数。默认情况下,它包含paneProportiondirectionpanePriority,允许所有可能的覆盖。

TwoPane 示例

Widget build(BuildContext context) {
  return TwoPane(
    startPane: _widgetA(),
    endPane: _widgetB(),
    paneProportion: 0.3,
    panePriority: MediaQuery.of(context).size.width > 500 ? TwoPanePriority.both : TwoPanePriority.start,
  );
}

Hinge Angle Sensor(铰链角度传感器)

折叠屏和双屏设备的两部分屏幕之间有一个铰链,这个铰链有一个传感器,报告这两部分屏幕之间的角度。例如,当这两部分平铺形成连续表面时,铰链角度报告180度的角度。

Hinge Angle API

要使用此插件,请在pubspec.yaml文件中添加dual_screen作为依赖项。

这将允许你导入DualScreenInfo import 'package:dual_screen/dual_screen.dart';

DualScreenInfo暴露了两个静态属性:

  • hingeAngleEvents:来自设备铰链角度传感器的广播流事件。如果没有配备铰链角度传感器,流不会产生事件。
  • hasHingeAngleSensor:返回一个Future,如果设备有铰链角度传感器则返回true。如果你的应用程序已经在使用MediaQuery.displayFeaturesMediaQuery.hinge来适应折叠屏或双屏形式因素,你可以安全地假设铰链角度传感器存在,并且hingeAngleEvents会产生可用值。

Hinge Angle 示例

import 'package:dual_screen/dual_screen.dart';

DualScreenInfo.hingeAngleEvents.listen((double hingeAngle) {
  print(hingeAngle);
});

DualScreenInfo.hasHingeAngleSensor.then((bool hasHingeSensor) {
  print(hasHingeSensor);
});

完整示例Demo

下面是一个完整的示例代码,展示了如何结合TwoPaneHinge Angle Sensor功能:

/// Copyright (c) Microsoft Corporation.
/// Licensed under the MIT License.

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

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: TwoPane(
        startPane: Scaffold(
          appBar: AppBar(
            title: const Text('Hinge Angle Sensor'),
          ),
          body: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                FutureBuilder<bool>(
                  future: DualScreenInfo.hasHingeAngleSensor,
                  builder: (context, hasHingeAngleSensor) {
                    return Text(
                        'Hinge angle sensor exists: ${hasHingeAngleSensor.data}');
                  },
                ),
                StreamBuilder<double>(
                  stream: DualScreenInfo.hingeAngleEvents,
                  builder: (context, hingeAngle) {
                    return Text('Hinge angle is: ${hingeAngle.data?.toStringAsFixed(2)}');
                  },
                ),
              ],
            ),
          ),
        ),
        endPane: Material(
          child: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Center(
              child: Text('This pane is visible on dual-screen devices.'),
            ),
          ),
        ),
        panePriority: TwoPanePriority.start,
      ),
    );
  }
}

通过以上内容,你可以了解如何在Flutter应用中使用dual_screen插件来支持双屏设备和铰链角度传感器的功能。希望这些信息对你有所帮助!


更多关于Flutter双屏支持插件dual_screen的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter双屏支持插件dual_screen的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用Flutter双屏支持插件dual_screen的代码案例。这个插件允许你在Flutter应用中检测和处理双屏设备(如微软的Surface Duo)的特定交互。

首先,你需要在你的pubspec.yaml文件中添加dual_screen依赖:

dependencies:
  flutter:
    sdk: flutter
  dual_screen: ^x.y.z  # 替换为最新版本号

然后,运行flutter pub get来安装依赖。

接下来,你可以在你的Flutter应用中使用这个插件。以下是一个简单的示例,展示如何检测双屏设备的连接状态以及获取屏幕信息。

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DualScreenInfoProvider(
      child: MaterialApp(
        title: 'Dual Screen Example',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: DualScreenHome(),
      ),
    );
  }
}

class DualScreenHome extends StatefulWidget {
  @override
  _DualScreenHomeState createState() => _DualScreenHomeState();
}

class _DualScreenHomeState extends State<DualScreenHome> with WidgetsBindingObserver {
  DualScreenInfo? _dualScreenInfo;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance!.addObserver(this);
    _dualScreenInfo = DualScreenInfo.maybeOf(context);
  }

  @override
  void dispose() {
    WidgetsBinding.instance!.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      // 当应用恢复时重新获取DualScreenInfo
      setState(() {
        _dualScreenInfo = DualScreenInfo.maybeOf(context);
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Dual Screen Support'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('Dual Screen Info:'),
            if (_dualScreenInfo != null) {
              Text('Is dual mode: ${_dualScreenInfo!.isDualMode ? 'Yes' : 'No'}'),
              Text('Hinge angle: ${_dualScreenInfo!.hingeAngle?.toInt()} degrees'),
              Text('Span mode: ${_dualScreenInfo!.spanMode ? 'Yes' : 'No'}'),
              Text('Primary screen bounds: ${_dualScreenInfo!.primaryScreenBounds}'),
              Text('Secondary screen bounds: ${_dualScreenInfo!.secondaryScreenBounds}'),
            } else {
              Text('Dual screen info not available'),
            },
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们做了以下几件事:

  1. 使用DualScreenInfoProvider包装整个应用,以便可以在应用的任何地方访问双屏信息。
  2. DualScreenHome组件的initState方法中,通过DualScreenInfo.maybeOf(context)获取双屏信息。
  3. 监听应用的生命周期状态变化,当应用从暂停状态恢复时重新获取双屏信息。
  4. 在UI中显示双屏设备的相关信息,如是否处于双屏模式、铰链角度、是否处于跨度模式以及主屏幕和次屏幕的边界。

请注意,这个示例代码假设你正在使用支持双屏的设备或模拟器进行测试。如果你没有这样的设备,你可能需要使用支持双屏模拟的模拟器(如Android Studio中的Surface Duo模拟器)来测试代码。

回到顶部