import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:shared_preferences/shared_preferences.dart'; /// 显示方向偏好:跟随系统 / 竖屏 / 横屏。 /// /// 与主题、语言并列,作为「我的」页可手动切换的显示设置;切换后通过 /// [SystemChrome.setPreferredOrientations] 实时生效,并重渲染界面(横屏沿用 /// NavigationRail 布局,竖屏沿用 NavigationBar 布局,二者共用同一套橙白主题, /// 视觉风格保持一致)。 enum DisplayOrientation { /// 跟随系统(默认):允许全部四个方向,由设备物理朝向决定。 system, /// 仅竖屏。 portrait, /// 仅横屏。 landscape, } const String _kDisplayOrientation = 'display_orientation'; /// 将偏好映射为 [SystemChrome] 需要的设备方向列表。 List deviceOrientationsFor(DisplayOrientation mode) { switch (mode) { case DisplayOrientation.portrait: return const [DeviceOrientation.portraitUp]; case DisplayOrientation.landscape: return const [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]; case DisplayOrientation.system: return const [ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight, ]; } } /// 立即应用显示方向(调用 [SystemChrome.setPreferredOrientations])。 void applyDisplayOrientation(DisplayOrientation mode) { SystemChrome.setPreferredOrientations(deviceOrientationsFor(mode)); } /// 从持久化读取已保存偏好;异常或无记录时返回 [DisplayOrientation.system]。 Future loadSavedOrientation() async { try { final prefs = await SharedPreferences.getInstance(); final v = prefs.getString(_kDisplayOrientation); if (v != null) { for (final e in DisplayOrientation.values) { if (e.name == v) return e; } } } catch (_) { // 忽略:SharedPreferences 不可用时退化为系统。 } return DisplayOrientation.system; } /// 显示方向偏好管理(持久化 + 实时生效)。 class DisplayOrientationNotifier extends Notifier { @override DisplayOrientation build() { // 首选项在 main 启动期已应用;这里异步回读以保证 UI 选中态与持久值一致。 _load(); return DisplayOrientation.system; } Future _load() async { final saved = await loadSavedOrientation(); if (saved != state) { state = saved; applyDisplayOrientation(saved); } } /// 切换显示方向:更新状态、即时生效并持久化。 Future set(DisplayOrientation mode) async { state = mode; applyDisplayOrientation(mode); try { final prefs = await SharedPreferences.getInstance(); await prefs.setString(_kDisplayOrientation, mode.name); } catch (_) { // 忽略持久化失败,运行时仍生效。 } } } /// 显示方向偏好提供者。 final displayOrientationProvider = NotifierProvider( DisplayOrientationNotifier.new, );