我实际上是想弄清楚该应用程序是在我的 Flutter 应用程序中运行在智能手机还是平板电脑上,但是包
device_info
只能告诉我们该设备,而不能告诉我该设备是智能手机还是平板电脑。
有没有办法通过检查设备的尺寸来做到这一点?
// 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
如果您无权访问 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';
}
其中一种方法是计算屏幕分辨率的对角线。
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;
}
}
尽管 iOS 在手机和平板电脑之间有明显的分离,但这在 Android 中不会发生。您需要根据屏幕宽度进行选择。
查看这篇文章以查看如何区分的示例:https://flutter.rocks/2018/01/28/implementing-adaptive-master-detail-layouts/
这里与其他问题相同,但返回
enum
而不是 bool
或 String
。由于它更封闭,所以使用起来更容易。
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 的灵感:·)
对于 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;
}
}
2023,Dart 3 解决方案的灵感来自 @bakua 的答案,还有 这个答案
bool get isTablet {
final firstView = WidgetsBinding.instance.platformDispatcher.views.first;
final logicalShortestSide = firstView.physicalSize.shortestSide / firstView.devicePixelRatio;
return logicalShortestSide > 600;
}
通常 Android 平板电脑和 iPad 的宽高比(宽度:高度)在 0.75 ~ 1.4 范围内,以下是最快的检查方法。我们可以根据长宽比调整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;
}
您可以使用
sizer包中的
DeviceType.tablet
。你会这样做:
SizerUtil.deviceType == DeviceType.tablet
该字段是使用此逻辑设置的,这与此处最接受的答案相同。我已经使用 sizer 来使我的应用程序具有响应能力,因此使用它来确定设备是否是平板电脑很方便。
您可以使用 flutter 中的 device_info_plus 包 https://pub.dev/packages/device_info_plus
static Future<bool> isTablet(BuildContext context) async {
bool isTab=false;
if (Platform.isIOS) {
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
if(iosInfo.model?.toLowerCase() == "ipad"){
isTab=true;
}else{
isTab=false;
}
return isTab;
} else {
var shortestSide = MediaQuery.of(context).size.shortestSide;
if(shortestSide > 600){
isTab=true;
}else{
isTab=false;
}
return isTab;
}}
打电话..
Future checkDeviceType() async {
bool iPad = await isTablet(context);
if(iPad){
//write your logic here..
}
}
创建 dart 文件
"size_config.dart"
import 'dart:io';
import 'package:flutter/widgets.dart';
import 'dart:async';
import 'package:device_info_plus/device_info_plus.dart';
class SizeConfig {
static late MediaQueryData _mediaQueryData;
static late double screenWidth;
static late double screenHeight;
static late double blockSizeHorizontal;
static late double blockSizeVertical;
static late double safeBlockHorizontal;
static late double safeBlockVertical;
static bool isIpad = false;
void init(BuildContext context) async {
_mediaQueryData = MediaQuery.of(context);
screenWidth = _mediaQueryData.size.width;
screenHeight = _mediaQueryData.size.height;
blockSizeHorizontal = screenWidth / 100;
blockSizeVertical = screenHeight / 100;
isIpad = await isTablet(context);
}
static Future<bool> isTablet(BuildContext context) async {
bool isTab = false;
if (Platform.isIOS) {
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
if (iosInfo.model.toLowerCase() == "ipad") {
isTab = true;
} else {
isTab = false;
}
return isTab;
} else {
var shortestSide = MediaQuery.of(context).size.shortestSide;
if (shortestSide > 600) {
isTab = true;
} else {
isTab = false;
}
return isTab;
}
}
}
打电话
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
var height = SizeConfig.screenHeight;
var width = SizeConfig.screenWidth;
bool isIpad = SizeConfig.isIpad;
我根据其他答案编写了这个上下文扩展,它对我有用:
extension ContextExt on BuildContext {
bool get isPhone => MediaQuery.of(this).size.width < 600.0;
bool get isTablet => MediaQuery.of(this).size.width >= 600.0;
}
用途:
final iconSize = context.isTablet ? 50.0 : 30.0;