如何在Flutter中仅针对手机设备锁定屏幕方向(不含平板/iPad)
嘿,这个需求我之前帮不少开发者实现过,其实核心就是先区分设备类型,再针对性设置屏幕方向,我给你两种靠谱的实现方式:
实现仅手机锁定屏幕方向的方案
核心思路
先判断当前设备是手机还是平板,手机端强制锁定你需要的方向(比如竖屏),平板端则保持系统默认的自由旋转逻辑,完美匹配你的需求。
方法一:用Flutter原生API判断(无需额外依赖)
这种方式通过屏幕最短边的长度来区分设备,是Flutter官方推荐的简易判断方案,适合大多数场景。
你可以在App的根Widget的initState方法里完成判断和方向设置:
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { @override void initState() { super.initState(); _setupScreenOrientation(); } Future<void> _setupScreenOrientation() async { // 获取当前设备的媒体查询数据 final mediaQuery = MediaQuery.of(context); // 定义平板的最短边阈值(通常用600dp,你可以根据自己的UI适配需求调整) const tabletThreshold = 600.0; final isTablet = mediaQuery.size.shortestSide >= tabletThreshold; if (!isTablet) { // 手机设备:锁定为竖屏(你也可以只保留portraitUp,禁止倒转) await SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); } else { // 平板设备:允许所有方向自由旋转 await SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight, ]); } } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('Screen Orientation Demo')), body: const Center(child: Text('Hello World')), ), ); } }
注意点
- 这里的
tabletThreshold可以灵活调整,比如如果你的平板UI适配是从720dp开始,就把阈值改成720.0就行。 - 把这个逻辑放在根Widget里,能确保全局所有页面都生效。
方法二:用device_info_plus精准判断(更可靠)
如果担心大屏手机被误判为平板,就用device_info_plus包获取设备的具体信息,这种方式能100%准确区分手机和平板。
步骤1:添加依赖
在pubspec.yaml里加入最新版本的device_info_plus:
dependencies: flutter: sdk: flutter device_info_plus: ^9.0.2 # 记得用pub上的最新版本
步骤2:实现判断逻辑
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:device_info_plus/device_info_plus.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { final DeviceInfoPlugin _deviceInfoPlugin = DeviceInfoPlugin(); @override void initState() { super.initState(); _setupScreenOrientation(); } Future<void> _setupScreenOrientation() async { bool isTablet = false; // 分别处理Android和iOS设备 if (Theme.of(context).platform == TargetPlatform.android) { final AndroidDeviceInfo androidInfo = await _deviceInfoPlugin.androidInfo; // Android直接通过系统提供的isTablet字段判断 isTablet = androidInfo.isTablet; } else if (Theme.of(context).platform == TargetPlatform.iOS) { final IosDeviceInfo iosInfo = await _deviceInfoPlugin.iosInfo; // iOS通过设备型号判断,iPad的型号里都会包含"iPad" isTablet = iosInfo.model.contains('iPad'); } if (!isTablet) { // 手机锁定竖屏 await SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, ]); } else { // 平板允许所有方向 await SystemChrome.setPreferredOrientations(DeviceOrientation.values); } } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('Screen Orientation Demo')), body: const Center(child: Text('Hello World')), ), ); } }
额外需要注意的细节
- iOS配置:如果你的iOS项目之前修改过
Info.plist里的方向设置,记得确保包含了你需要的方向,否则锁定逻辑可能不生效。 - 动态调整:如果用户使用过程中设备状态变化(比如外接显示器),可以监听
MediaQuery的尺寸变化,重新执行方向设置逻辑,保证适配准确。 - 全面测试:一定要在不同尺寸的手机、平板上测试,确保判断逻辑不会出错,方向锁定符合预期。
内容的提问来源于stack exchange,提问作者Chanaka
相关产品推荐
相关产品推荐

