flutter 控制iOS设备屏幕可旋转支持方向

Flutter横屏实践 阅读详情

场景:flutter开发一个app,非module形式,即:app内部大部分页面是横屏,有部分页面是需要视屏显示(不参与喷子:写一个空控件旋转90度不就好了?但是这样的话状态栏之前的状态,如果你不需要状态栏的话那也没关系。我们不扯远,这里只是单纯的做技术的屏幕可旋转实现,来实现flutter控制iOS设备屏幕可旋转的可设定方位的限制)

下面我来讲一下关于iOS屏幕旋转的有效实现的三种方式,都是可以实现的,只是不同场景,由易到复杂递增,可根据不同的需求来选择参考使用,也希望能对你的成长有所帮助。

屏幕旋转控制方案我总结起来有三种(在不同场景下读是可以满足的):

一,开发工具直接限制可转动方向(不推荐),虽然我们开发的过程中经常是这样用的,方便快捷。但是这个前提下不满足)

二、用代码控制单个屏幕旋转与否(你可以统一继承,这里是从原理上是单个页面的处理方式来讲的)

override var shouldAutorotate: Bool

override var supportedInterfaceOrientations: UIInterfaceOrientationMask

这两个方法就可以控制屏幕的旋转和可支持的旋转方向了,具体实现应该网上很多了,就不再赘述了。

三、flutter app开发,通过桥接开控制,仿照现有的SystemChrome通过桥接控制,

那就会有小朋友讲:为什么不用SystemChrome来控制,答案是现在还没有兼容iOS,你可以试试就会发现这个问题。不然也不会有这篇文章的出现了。😄!

SystemChrome.setPreferredOrientations([
    DeviceOrientation.landscapeRight,
    DeviceOrientation.landscapeRight,
  ]);

也会有人说,不是还有一个orientation。答案是一样的效果。目前都是对安卓可以,但是iOS不支持,看也有给flutter官方提出这个问题,但是还没有得到解决。

那么接下来,我们就仿照官方推荐的SystemChrome来建立一个iOS的桥接来实现:

第一步我们先实现iOS这边的代码和桥接:

创建一个继承与NSObject的一个工具类FlutterIOSDevicePlugin来同一处理桥接事件接收

//
//  FlutterIOSDevicePlugin.h
//  Runner
//
//  Created by 曹世鑫 on 2020/7/9.
//

#import <Foundation/Foundation.h>
#import <Flutter/Flutter.h>

NS_ASSUME_NONNULL_BEGIN

@interface FlutterIOSDevicePlugin : NSObject

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar flutterViewController:(nullable FlutterViewController*) controller;

- (instancetype)newInstance:(NSObject<FlutterPluginRegistrar>*)registrar flutterViewController:(nullable FlutterViewController*) controller;


@end

NS_ASSUME_NONNULL_END
//
//  FlutterIOSDevicePlugin.m
//  Runner
//
//  Created by 曹世鑫 on 2020/7/9.
//

#import "FlutterIOSDevicePlugin.h"
#import <UIKit/UIKit.h>

@interface FlutterIOSDevicePlugin () {
    NSObject<FlutterPluginRegistrar> *_registrar;
    FlutterViewController *_controller;
    UIDeviceOrientation iOSOrientation;
    UIDeviceOrientation lastLandOrientation;
}
@end

static NSString *const CHANNEL_NAME = @"flutter_ios_device_rotation";
static NSString *const METHOD_CHANGE_ORIENTATION = @"change_screen_orientation";

@implementation FlutterIOSDevicePlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
    FlutterMethodChannel *channel = [FlutterMethodChannel
                                     methodChannelWithName:CHANNEL_NAME
                                     binaryMessenger:[registrar messenger]];
    FlutterIOSDevicePlugin *instance = [[FlutterIOSDevicePlugin alloc] newInstance:registrar flutterViewController:nil];
    [registrar addMethodCallDelegate:instance channel:channel];
}

+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar flutterViewController:(FlutterViewController*) controller {
    FlutterMethodChannel *channel = [FlutterMethodChannel
                                     methodChannelWithName:CHANNEL_NAME
                                     binaryMessenger:[registrar messenger]];
    FlutterIOSDevicePlugin *instance = [[FlutterIOSDevicePlugin alloc] newInstance:registrar flutterViewController:controller];
    [registrar addMethodCallDelegate:instance channel:channel];
}

- (instancetype)newInstance:(NSObject<FlutterPluginRegistrar>*)registrar flutterViewController:(FlutterViewController*) controller{
    _registrar = registrar;
    _controller = controller;
    iOSOrientation = [UIDevice currentDevice].orientation;
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(rotateDevice:) name:UIDeviceOrientationDidChangeNotification object:nil];
    return self;
}

- (void)rotateDevice:(NSObject *)sender {
    UIDevice *device = [sender valueForKey:@"object"];
    iOSOrientation = device.orientation;
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil];
}

- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
    if ([METHOD_CHANGE_ORIENTATION isEqualToString:call.method]) {
        NSNumber *index = [NSNumber numberWithInt: [call.arguments[0] intValue]];
        if ([index isEqualToNumber:@0]) {
            if (iOSOrientation == UIDeviceOrientationLandscapeLeft || iOSOrientation == UIDeviceOrientationLandscapeRight){
                lastLandOrientation = iOSOrientation;
            }
            iOSOrientation = UIDeviceOrientationPortrait;
        } else if([index isEqualToNumber:@1]){
            iOSOrientation = UIDeviceOrientationLandscapeLeft;
        } else if([index isEqualToNumber:@2]){
            iOSOrientation = UIDeviceOrientationLandscapeRight;
        } else if([index isEqualToNumber:@3]){
            if (iOSOrientation != UIDeviceOrientationPortrait && iOSOrientation != UIDeviceOrientationPortraitUpsideDown){
                iOSOrientation = UIDeviceOrientationPortrait;
            }
        } else if([index isEqualToNumber:@4]){
            if (iOSOrientation != UIDeviceOrientationLandscapeLeft && iOSOrientation != UIDeviceOrientationLandscapeRight){
                if (lastLandOrientation) {
                    iOSOrientation = lastLandOrientation;
                } else {
                    iOSOrientation = UIDeviceOrientationLandscapeLeft;
                }
            }
            lastLandOrientation = iOSOrientation;
        } else if([index isEqualToNumber:@6]){
            if (iOSOrientation == UIDeviceOrientationPortraitUpsideDown) {
                iOSOrientation = UIDeviceOrientationPortrait;
            }
        }
        [[UIDevice currentDevice] setValue:@(iOSOrientation) forKey:@"orientation"];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"FlutterIOSDevicePlugin" object:nil userInfo:@{@"orientationMask": index}];
        [UIViewController attemptRotationToDeviceOrientation];
        result(nil);
    } else {
        result(FlutterMethodNotImplemented);
    }
}


@end

这里我们在handleMethodCall里面设置了设备的方向,并通过[UIViewController attemptRotationToDeviceOrientation];来刷新设备的展示,事件里面看到我们发出了一个通知:[[NSNotificationCenter defaultCenter] postNotificationName:@"FlutterIOSDevicePlugin" object:nil userInfo:@{@"orientationMask": index}];

是通过通知将收到的参数传递到AppDelegate里面,进而控制设备旋转刷新的时候的可支持方向(下面我会贴上AppDelegate.swift的代码)

这里介绍设置设备方向代码,下面我列出了两种都可以,一个是kvc形式,一个是runtime形式(也可以说是kvc的内部实现方式)

 //1.设置屏幕的转向为竖屏
    [[UIDevice currentDevice] setValue:@(UIDeviceOrientationPortrait) forKey:@"orientation"];


//2.设置屏幕的转向为竖屏
- (void)interfaceOrientation:(UIInterfaceOrientation)orientation{
  if([[UIDevicecurrentDevice] respondsToSelector:@selector(setOrientation:)]) {        
      SEL selector  =NSSelectorFromString(@"setOrientation:");
      NSInvocation*invocation = [NSInvocationinvocationWithMethodSignature:[UIDeviceinstanceMethodSignatureForSelector:selector]];     
      [invocation setSelector:selector];        
      [invocation setTarget:[UIDevicecurrentDevice]];
      intval = orientation;
      // 从2开始是因为0 1 两个参数已经被selector和target占用
      [invocation setArgument:&val atIndex:2];                                                     
      [invocation invoke];   
  }}

下面我们来看AppDelegate.swift里面的代码(这里有一部分是flutter app已经加入的,比如didFinishLaunchingWithOptions里面的GeneratedPluginRegistrant注册)

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    
    var orientationMask: UIInterfaceOrientationMask = .all;
    
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    NotificationCenter.default.addObserver(self, selector: #selector(changeLandscape(center:)), name:NSNotification.Name(rawValue: "FlutterIOSDevicePlugin"), object: nil)
    GeneratedPluginRegistrant.register(with: self)
    FlutterIOSDevicePlugin.register(with: self.registrar(forPlugin: "FlutterIOSDevicePlugin"), flutterViewController: nil)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
    
    override func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
        return orientationMask;
    }
    
    @objc func changeLandscape(center: Notification){
        let index: NSNumber = (center.userInfo?["orientationMask"] ?? 5) as! NSNumber
        orientationMask = OrientationUtil.getOrientationMaskWithIndex(number: index)
        _ = application(UIApplication.shared, supportedInterfaceOrientationsFor: UIApplication.shared.keyWindow)
    }
    
}

这里我们在设备支持方向的代码中添加了自定义的方向设定,在接收到通知的方法中处理好支持的方向类型,然后我们可以手动调用一下supportedInterfaceOrientationsFor来实现一下触发。

 

另外这里用到swift调用oc的实现。所以我们需要在已存在的桥接文件Runner-Bridging-Header.h里面加入我们的oc头文件(如果你想了解怎么创建桥接文件可以自行百度,这里不再做赘述),结果如下:

#import "GeneratedPluginRegistrant.h"
#import "FlutterIOSDevicePlugin.h"

可以看到AppDelgate.swift里面有一个changeLandscape来处理通知接收到的信息的OrientationUtil用来处理(这里的对应关系要和flutter端的定义一一对应,这里两端都是我写的,哈哈,就我自己和自己协商了,就都按照iOS官方的命名来近似定义了):

//
//  OrientationUtil.swift
//  Runner
//
//  Created by 曹世鑫 on 2020/7/10.
//

import UIKit

class OrientationUtil: NSObject {
    
    //转化工具
   static func getOrientationMaskWithIndex(number: NSNumber) -> UIInterfaceOrientationMask {
        var mask : UIInterfaceOrientationMask = .all
        switch number {
        case 0:
            mask = .portrait
            break
        case 1:
            mask = .landscapeLeft
            break
        case 2:
            mask = .landscapeRight
            break
        case 3:
            mask = .portraitUpsideDown
            break
        case 4:
            mask = .landscape
            break
        case 5:
            mask = .all
            break
        case 6:
            mask = .allButUpsideDown
            break
        
        default:
            mask = .all
            break
        }
        return mask
    }
}

接下来。我们就转向flutter代码:

首先我们创建一个屏幕旋转的桥接类,由于安卓得不需要,这里我就单设置iOS的了:ScreenRotationiOS

class ScreenRotationiOS {
  static const MethodChannel _channel = MethodChannel('flutter_ios_device_rotation');

  static Future changeScreenOrientation(DeviceOrientationMask orientationMask) {
    return _channel.invokeMethod('change_screen_orientation', [orientationMask.index]);
  }
}

enum DeviceOrientationMask {
  //竖屏
  Portrait,
  //左旋转
  LandscapeLeft,
  //右旋转
  LandscapeRight,
  //竖直方向向上向下可旋转
  PortraitUpsideDown,
  //横屏
  Landscape,
  //全部四个方位
  All,
  //左右旋转
  AllButUpsideDown,
}

可以看到这里的注释枚举是和iOS方面的switch的接收是一一对应的。

 

接下来就是使用:

在flutter代码中需要设置的地方:

if (Platform.isIOS) {
      await ScreenRotationiOS.changeScreenOrientation(
                DeviceOrientationMask.Landscape);
    } 

内容枚举自定义选择。

这里我们也可以不用加上判断是iOS平台才执行,但是本着之后代码的清晰,防止新来小伙伴再以为安卓里面也有定义的桥接造成不必要的误会,建议还是使用的地方加上iOS平台的判断。

然后就写一个demo来看一下效果吧:

至此,全部结束!

 

偶然遇到的小问题:

1.运行在iphone上面有效果,在ipad上面触发没反应。还是会上下左右任性的旋转。

解决办法:在iOS项目中打开info.plist打开全屏显示:

 

喜欢的小朋友们可以关注我一下吧。我会及时更新有意义的技术文章和攻坚点的。

 

已发布到pub.dev,项目中使用到的同学,可以直接yaml里面添加依赖:limiting_direction_csx  喜欢的可以点一个like,鼓励一下。谢谢了。

 

Flutter中获取监听屏幕方向、锁定屏幕方向 Flutter中获取屏幕方向和控制屏幕方向 阅读详情

相关推荐

解决Flutter旋转屏幕状态栏空缺的问题

【flutter】解决打孔屏旋转屏幕,原状态栏位置空缺的问题。

weixin_44354735的博客 1397

Flutter 实现 App 内更新安装包

背景 目前flutter发展火热,生态越来越繁荣,但相比于原生开发,仍非常稚嫩,使用起来坑很多,最近做需求——app内完成安装包的更新,完成该功能踩了很多的坑,现在记录一下实现过程。 实现过程 获取当前app的版本、平台信息 static String _version; static String _flatform; import 'package:package_info/pack...

Android 开发架构 2682

Flutter 横竖屏控制实战:SystemChrome.setPreferredOrientations详解

本文详细解析了Flutter中SystemChrome.setPreferredOrientations的使用方法,帮助开发者精准控制应用横竖屏显示。从基础配置到高级技巧,涵盖全局锁定、单页面控制及动画处理等实战场景,并针对平板设备和iOS特殊情况提供解决方案,助力提升应用用户体验。

weixin_29009501的博客 310

swift3 设置设备方向支持(supportedInterfaceOrientations)

1、改变整个app的设备方向支持 2、代码改变app不同场景的设备旋转方向支持(可以在不同的viewController中处理对设备方向的不同需求)override var supportedInterfaceOrientations: UIInterfaceOrientationMask{ return .portrait }设置之后当前的控制器和子控制器都会遵守这个

EIamor的博客 5875

Flutter页面方向控制全攻略:如何用SystemChrome实现灵活的横竖屏切换(含动态调整技巧)

本文深入解析了如何在Flutter应用中利用SystemChrome实现灵活的横竖屏控制。从全局配置到页面级动态切换,详细介绍了setPreferredOrientations方法的使用技巧、与路由及状态管理的结合方案,并提供了视频播放器等实战场景的避坑指南,帮助开发者打造无缝的屏幕方向切换体验。

weixin_29002595的博客 121

Flutter悬浮窗组件flutter_floating开发指南

悬浮窗是现代移动应用中常见的UI组件,它通过浮动在应用界面之上的方式提供快捷功能入口。其技术原理主要基于视图层级管理和手势交互系统,在Flutter中通过Overlay和GestureDetector等基础组件实现。flutter_floating作为专门优化的开源库,解决了跨平台适配、位置记忆、边缘吸附等工程难题,大幅降低了开发复杂度。该组件适用于媒体控制器、游戏辅助工具、实时状态显示等多种场景,特别适合需要保持全局可见性的功能模块。通过分层架构设计和灵活的API配置,开发者可以快速实现从简单悬浮按钮到复

weixin_42692935的博客 250

Flutter控制屏幕旋转

特定页面旋转屏幕很简单: SystemChrome.setPreferredOrientations([ ... ]); 数组中是您要支持的屏幕方向. 如果想在特定页面固定横屏, 您可以这样写: @override void initState() { super.initState(); SystemChrome.setPreferredOrienta...

aau88497的博客 2504

Flutter旋转屏幕,Flutter旋转屏幕

Flutter旋转屏幕,Flutter旋转屏幕

旋转动画Rotation Transition-Flutter 适配OpenHarmony

Flutter旋转动画开发指南:RotationTransition核心应用与优化 本文详细介绍了Flutter中RotationTransition组件的使用方法和企业级应用场景。主要内容包括:旋转动画的核心概念(旋转范围、对齐方式等)、基础代码实现、高级应用技巧(响应式设计、动画曲线优化、无障碍支持等),以及PC端适配要点。文章特别强调了在企业级应用中需要考虑的性能优化、多设备适配和交互体验问题,并提供了加载动画、菜单展开等实际应用场景的代码示例。最后给出了扩展建议,帮助开发者实现更复杂的旋转动画效果。

suyuhan123456的博客 956

Flutter 控制屏幕旋转的实现

最近需要做个平板的项目,然后需要直接横屏,有2种实现方式。 1, 随着屏幕旋转,布局自动调整。做横竖屏适配 2,强制屏幕横屏,不随着屏幕去调整 第一种方式这里就不做说明了。代码做适配就可以。 下面说一下第二种实现方式 Flutter 自带方式 flutter 为我们提供了方法来控制系统的横竖屏显示 SystemChrome.setPreferredOrientations([ DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight, DeviceOrientation.portraitUp,

(精读)揭示多元时间序列的高阶组织

时间序列分析已经被证明是刻画生物学、神经科学和经济学中的一些现象以及理解它们的一些潜在动力学特征的有力方法。尽管针对多元时间序列的分析已经提出了很多方法,但大多数方法都忽略了非成对相互作用对涌现动力学的影响。在这里,我们提出了一个新的框架来刻画多元时间序列中高阶依赖关系的时间演化。利用网络分析和拓扑学,我们表明,与传统的基于成对统计的工具不同,我们的框架鲁棒地区分了耦合混沌映射的各种时空状态,包括混沌动力学阶段和各种类型的同步。

weixin_53406075的博客 2412

Flutter旋转轮盘插件安装与配置完全指南

Flutter旋转轮盘插件安装与配置完全指南 项目基础介绍与编程语言 项目名称: Flutter Spinning Wheel 开发者: David Anaya 编程语言: 主要采用Dart语言,适用于Flutter框架。 项目简述: Flutter Spinning Wheel是一款高度可定制化的旋转轮盘小部件,专为Flutter应用设计,允许开发者轻松集成抽奖转盘功能至其应用之中。它支持自定义...

gitblog_01248的博客 820

深入解析:如何基于开源p-net快速开发Profinet从站服务

开源p-net协议栈为工业设备开发者打开了通往Profinet世界的大门。随着工业互联网的发展,软协议栈方案将在边缘计算领域展现更大潜力。该文章完整实现了PROFINET从站的核心功能,可直接作为产品开发的基础框架。实际部署时需根据具体硬件平台调整网络驱动和实时性配置。

极地星辰 3881

如何实现ios屏幕的横竖屏自适应

首先在UIViewController的 -(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 方法中设置设备要支持的deviceOrientation; 在UIViewController的 -(void)willRotateToInterface...

azkslxjb328879的博客 182

hcaptcha-challenger:基于本地AI模型自动破解验证码的工程实践

验证码作为区分人类与机器的经典安全机制,其核心原理是通过图像识别、行为分析等交互式挑战来阻挡自动化程序。传统绕过方法依赖第三方打码平台或脚本,存在成本高、稳定性差的问题。随着多模态大语言模型和计算机视觉技术的发展,本地化AI求解成为新的技术方向,它通过集成YOLO、ResNet等模型,在本地完成图像语义理解,实现了高隐私、低成本、可进化的验证码自动化解决方案。这种范式尤其适用于需要大规模稳定处理网页交互的场景,如电商数据采集和社交媒体管理。hcaptcha-challenger项目正是这一理念的工程实践,它

weixin_42587866的博客 1026

【openwrt-21.02】T750 openwrt 双系统说明及切换方法

高度集成的 T750 平台大幅减少组件数量,为产品设计者提供更小的尺寸和更低的功耗。T750 采用先进的 7nm 制程,高度集成 5G 调制解调器和四核 Arm CPU,提供较强的功能和配置,设备制造商得以打造精巧的高性能 CPE 产品,如固定无线接入(FWA)路由器和移动热点。3. preloader 加载并启动 A 系统,若 A 系统的任一启动阶段加载失败,preloader 将重新加载并启动 A 系统 3 次,若 3 次均失败,则自动切换至 B 系统,加载并启动 B 系统。A/B 系统切换流程如下。

wgl307293845的博客 1416

Flutter auto_orientation 插件在鸿蒙系统上的使用指南

auto_orientation 是一个 Flutter 插件,用于控制应用屏幕方向,支持 iOS、Android 和 HarmonyOS 平台。该插件提供了丰富的 API 来手动或自动控制屏幕旋转,适用于视频、游戏等场景。安装需通过 Git 引入依赖,并在 HarmonyOS 中配置网络权限。核心 API 包括 landscapeLeftMode()、portraitUpMode() 等方法,支持横向、纵向及自动旋转模式。示例代码展示了如何通过按钮切换不同屏幕方向,为开发者提供了灵活的方向控制方案。

b13053810049的博客 952

让旧 Append 字段升级为真正的 Key User Custom Field:基于 SCFD_EUI 的无损转换与 UI / API 暴露实战

摘要:SAP S/4HANA私有云和本地部署项目中,常面临将历史遗留的手工追加字段转换为可管理的Custom Field的挑战。SAP提供通过事务码SCFD_EUI将旧字段转换为ABAP Managed Field(AMF)的路径,实现字段名和数据原地保留的同时获得扩展能力。适用场景包括已沉淀多年数据的字段迁移成本高,或对数据元素有特殊约束需求。转换后字段可在Fiori UI、报表、表单等多触点统一管理。但AMF会增加复杂度,建议优先使用标准Custom Field。操作前需确保开发环境和传输配置正确,并遵

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 247

Flutter 41: 图解神秘的 SystemChrome

小菜在切换横竖屏时用到 SystemChrome,小菜理解它作为一个全局属性,很像 Android 的 Application,功能很强大。 setPreferredOrientations 在我们日常应用中可能会需要设置横竖屏,或锁定单方向屏幕等不同要求,通过 setPreferredOrientations 配合实现;简单可以...

测试0901-1 1908

ABB机器人与S7-1200PLC实现位置坐标数据发送和接收的具体方法

ABB机器人与S7-1200PLC实现位置坐标数据发送和接收的具体方法

Robot_PLC_HMI_Automation 2917

1.2 机器人控制系统软硬件平台

工业机器人的软硬件平台架构是影响工业机器人性能和效率的重要因素。良好的软硬件平台架构可以帮助工业机器人更加稳定和高效地完成工作,提高生产效率。正确的软硬件配置还可以提高工业机器人的灵活性和可靠性,使其能够更好地适应不断变化的生产环境。 同时,工业机器人的软硬件平台架构还可以影响工业机器人的安全性和维护成本。如果软硬件平台架构不合适,工业机器人可能出现故障或安全隐患,需要大量的维护和维修费用。因此,选择适当的软硬件平台架构对于确保工业机器人的高效运行和长期使用是非常重要的。

Galaxy_Robot的博客 2万+

关于iOS控制单个viewcontroller旋转需要注意的地方

具体参考:http://blog.youkuaiyun.com/yiyaaixuexi/article/details/8035014

_闲花_de_ios笔记 723

【招商银行笔试题汇总】[全网首发]2024-04-23-招商银行春秋招笔试题-三语言题解(CPP/Python/Java)

🏳️ 难难难!!!本次招商银行的笔试算是今年春招最难的场次之一了K小姐所在的公司有 NNN 个部门,编号从 111 到 NNN。由于公司网络系统比较老旧,对于同一个数据 ddd,不同部门记录的值可能不同。数据 ddd 在各部门被记录为 d1,d2,...,dNd_1, d_2, ..., d_Nd1​,d2​,...,dN​。公司提出可以通过会议来实现数据的一致性。每次会议会让相邻编号范围内的所有部门一起参加,如果有超过半数的部门能够对数据 ddd 的值达成共识,那么在此次会议后,参与会议的所有部门会将

春秋招笔试突围 3463

Flutter三方库 HarmonyOS ArkTS API 24 flutter_card_swiper 适配 OpenHarmony —— 实现卡片任意方向滑动

本项目是一个结构清晰、功能聚焦的 Flutter 组件演示应用,展示了如何在 Flutter 中集成和使用第三方 UI 组件库,并将其封装为可复用的自定义组件。技术亮点体现在以下几个方面:第一是组件封装思想。将第三方库的复杂用法封装在内部,对外暴露简洁的属性接口,提高了代码的可读性和可维护性。上层使用者只需要提供卡片列表和滑动回调,无需了解底层库的具体实现细节。这种封装也使得未来更换底层滑动库时,只需要修改组件内部实现即可,不会影响上层调用代码。第二是生命周期管理。

2301_79516858的博客 401

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Flutter视频播放器终极指南:flutter_ijkplayer常见问题解决与性能优化

Flutter_ijkplayer是Flutter生态中功能强大的视频播放器插件,基于bilibili的ijkplayer核心,支持多种视频格式和高级播放功能。本文将深入解析flutter_ijkplayer的常见问题解决方案,包括模拟器显示异常、播放错误处理以及性能优化技巧,帮助开发者快速上手并解决实际开发中的痛点。 ## 📱 iOS模拟器显示问题深度解析 **核心问题**:iOS模拟器有

gitblog_02047的博客 461

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

上一篇: git你会用到的命令
下一篇: 解决TestFlight 链接分享无法打开问题
Cao_Shixin攻城狮
博客等级 码龄10年 710粉丝 102原创
评论 12
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值