【问题标题】:Can we check the device to be smartphone or tablet in Flutter?我们可以在 Flutter 中检查设备是智能手机还是平板电脑?
【发布时间】:2018-09-04 04:33:28
【问题描述】:

我实际上是想在我的颤振应用程序中确定该应用程序是在智能手机还是平板电脑上运行,但 device_info 包只能说明设备,而不能说明设备是智能手机还是平板电脑。有没有办法通过检查设备的大小来做到这一点?

非常感谢 鲯鳅

【问题讨论】:

  • 您如何定义智能手机和平板电脑之间的区别?是设备能不能打电话吗?
  • 嗨@GünterZöchbauer 是的,智能手机我的意思是可以拨打电话的设备,因为我的应用程序中有一个选项可以呼叫联系人,但如果设备无法拨打电话,我想隐藏此选项来电。
  • 我认为目前不直接支持。您始终可以使用插件flutter.io/developing-packages 调用像stackoverflow.com/questions/5196833/… 这样的本机服务。有很多例子github.com/flutter/plugins/tree/master/packages
  • 谢谢@GünterZöchbauer 我会试一试,看看这是否有效,我不确定iOS,但会检查它以及答案中提到的谢谢你的帮助。跨度>
  • 为什么要排除像 Skype 这样的 VOIP 通话?仅仅因为它没有电话号码并不意味着它不能拨打电话。

标签: flutter dart tablet smartphone devicecheck


【解决方案1】:
// The equivalent of the "smallestWidth" qualifier on Android.
var shortestSide = MediaQuery.of(context).size.shortestSide;

// Determine if we should use mobile layout or not, 600 here is
// a common breakpoint for a typical 7-inch tablet.
final bool useMobileLayout = shortestSide < 600;

复制自https://flutter.rocks/2018/01/28/implementing-adaptive-master-detail-layouts/

感谢@Sergi

【讨论】:

  • 注:以屏幕宽度为基准来确定平板/手机是Android官方的处理方式,所以对Flutter也应该有好处
  • 这给了我 552 在我的 Galaxy 平板电脑和 nexus 7 标签模拟器
  • 是的!只是更改我的答案,但是当我使用您的解决方案时,您遇到了与我相同的问题。我的答案现在使用550 而不是600 作为幻数。这是因为该值会根据设备方向而变化。我猜是因为它只考虑了窗口空间,所以当设备处于横向时,状态栏和导航栏会从最短的一侧获得一些空间。因此,600 适用于普通平板电脑,但当您使用 Nexus 7 2012 等较小的平板电脑时,它会将其视为手机。
【解决方案2】:

如果您无权访问 BuildContext,则可以使用它。我从sdk/flutter/packages/flutter/lib/src/widgets/app.dart:1252取出来的。

  String getDeviceType() {
    final data = MediaQueryData.fromWindow(WidgetsBinding.instance.window);
    return data.size.shortestSide < 600 ? 'phone' :'tablet';
  }

【讨论】:

  • 是的!只是更改我的答案,但是当我使用您的解决方案时,您遇到了与我相同的问题。我的答案现在使用550 而不是600 作为幻数。这是因为该值会根据设备方向而变化。我猜是因为它只考虑了窗口空间,所以当设备处于横向时,状态栏和导航栏会从最短的一侧获得一些空间。因此,600 适用于普通平板电脑,但当您使用 Nexus 7 2012 等较小的平板电脑时,它会将其视为手机。
【解决方案3】:

其中一种方法是计算屏幕分辨率的对角线。

import 'package:flutter/widgets.dart';
import 'dart:math';

class TabletDetector {

  // iPhone 6S 
  // |_ [portrait]
  //    |_ size: 375.0x667.0, pixelRatio: 2.0, pixels: 750.0x1334.0
  //       |_ diagonal: 765.1888655750291
  // |_ [horizontal]
  //    |_ size: 667.0x375.0, pixelRatio: 2.0, pixels: 1334.0x750.0
  //       |_ diagonal: 765.1888655750291

  // iPhone X 
  // |_ [portrait]
  //    |_ size: 375.0x812.0, pixelRatio: 3.0, pixels: 1125.0x2436.0
  //       |_ diagonal: 894.4098613052072
  // |_ [horizontal]
  //    |_ size: 812.0x375.0, pixelRatio: 3.0, pixels: 2436.0x1125.0
  //       |_ diagonal: 894.4098613052072

  // iPhone XS Max 
  // |_ [portrait]
  //    |_ size: 414.0x896.0, pixelRatio: 3.0, pixels: 1242.0x2688.0
  //       |_ diagonal: 987.0217829409845
  // |_ [horizontal]
  //    |_ size: 896.0x414.0, pixelRatio: 3.0, pixels: 2688.0x1242.0
  //       |_ diagonal: 987.0217829409845

  // iPad Pro (9.7-inch) 
  // |_ [portrait]
  //    |_ size: 768.0x1024.0, pixelRatio: 2.0, pixels: 1536.0x2048.0
  //       |_ diagonal: 1280.0
  // |_ [horizontal]
  //    |_ size: 1024.0x768.0, pixelRatio: 2.0, pixels: 2048.0x1536.0
  //       |_ diagonal: 1280.0

  // iPad Pro (10.5-inch) 
  // |_ [portrait]
  //    |_ size: 834.0x1112.0, pixelRatio: 2.0, pixels: 1668.0x2224.0
  //       |_ diagonal: 1390.0
  // |_ [horizontal]
  //    |_ size: 1112.0x834.0, pixelRatio: 2.0, pixels: 2224.0x1668.0
  //       |_ diagonal: 1390.0

  // iPad Pro (12.9-inch) 
  // |_ [portrait]
  //    |_ size: 1024.0x1366.0, pixelRatio: 2.0, pixels: 2048.0x2732.0
  //       |_ diagonal: 1707.2000468603555
  // |_ [horizontal]
  //    |_ size: 1366.0x1024.0, pixelRatio: 2.0, pixels: 2732.0x2048.0
  //       |_ diagonal: 1707.2000468603555

  static bool isTablet(MediaQueryData query) {
    var size = query.size;
    var diagonal = sqrt(
      (size.width * size.width) + 
      (size.height * size.height)
    );

    /*
    print(
      'size: ${size.width}x${size.height}\n'
      'pixelRatio: ${query.devicePixelRatio}\n'
      'pixels: ${size.width * query.devicePixelRatio}x${size.height * query.devicePixelRatio}\n'
      'diagonal: $diagonal'
    );
    */

    var isTablet = diagonal > 1100.0;
    return isTablet;
  }
}

【讨论】:

  • 我通过使函数内部 _isTablet 不带参数来稍微改变了这一点。然后暴露了一个在其中使用MediaQueryData.fromWindow(WidgetsBinding.instance!.window) 的无参数方法。在这里学习一下。我是 Swift 的一名皈依者,我的脚趾浸入飞镖池中。
【解决方案4】:

尽管 iOS 明确区分了手机和平板电脑,但在 Android 中不会发生这种情况。您需要根据屏幕宽度进行选择。

查看这篇文章以查看有关如何区分的示例:https://flutter.rocks/2018/01/28/implementing-adaptive-master-detail-layouts/

【讨论】:

  • 您好,感谢您的回复,我将尝试这个示例,看看是否有帮助。非常感谢
【解决方案5】:

这里与其他 aswers 相同,但返回 enum 而不是 boolString。越封闭越容易使用。

import 'package:flutter/widgets.dart';

enum DeviceType { Phone, Tablet }

DeviceType getDeviceType() {
  final data = MediaQueryData.fromWindow(WidgetsBinding.instance.window);
  return data.size.shortestSide < 550 ? DeviceType.Phone : DeviceType.Tablet;
}

感谢@Chandler 和@bakua 的启发:·)

【讨论】:

  • 编辑!现在幻数是550 而不是600。这是因为该值会根据设备方向而变化。我猜是因为它只考虑了窗口空间,所以当设备处于横向时,状态栏和导航栏会从最短的一侧获得一些空间。因此,600 适用于普通平板电脑,但当您使用 Nexus 7 2012 等较小的平板电脑时,它会将其视为手机。在这种情况下,当设备处于横向时,最短的边会给出552。所以,大到550 作为幻数!
  • 我喜欢这个解决方案,但我觉得它可以通过将其转换为 K getter 来进一步改进,这样感觉就像其他颤振系统常量,如 kIsWeb DeviceType get kDeviceType { ... }
  • @JasonPerfetto 这也是个好主意:·)
【解决方案6】:

对于Android,正如@Chandler 所说,您应该检查屏幕的最小尺寸,但对于iOS,您可以使用device_info 包以100% 的准确度识别它是否是iPad:

添加pubspec.yaml:

device_info: ^0.4.2+4

  static Future<bool> isTablet(BuildContext context) async {

    if (Platform.isIOS) {
      DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
      IosDeviceInfo iosInfo = await deviceInfo.iosInfo;

      return iosInfo.model.toLowerCase() == "ipad";
    } else {
      // The equivalent of the "smallestWidth" qualifier on Android.
      var shortestSide = MediaQuery.of(context).size.shortestSide;

      // Determine if we should use mobile layout or not, 600 here is
      // a common breakpoint for a typical 7-inch tablet.
      return shortestSide > 600;
    }
  }

【讨论】:

    【解决方案7】:

    Android Tablet 和 iPad 的宽高比(宽:高)通常在 0.75 ~ 1.4 的范围内,以下是最快的检查方法。我们可以根据Aspect ratio调整UI。

    bool isTablet;
    double ratio = MediaQuery.of(context).size.width / MediaQuery.of(context).size.height;
    if( (ratio >= 0.74) && (ratio < 1.5) )
    {
      isTablet = true;
    } else{
      isTablet = false;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-21
      • 2012-07-05
      • 2012-07-06
      • 2016-11-09
      • 2013-05-28
      相关资源
      最近更新 更多