写点什么

harmony_flutter_orientation_plugins(监听屏幕状态插件)

作者:flfljh
  • 2024-12-18
    湖南
  • 本文字数:5382 字

    阅读完需:约 18 分钟

harmony_flutter_orientation(屏幕旋转)

flutter 端监听鸿蒙手机得屏幕横竖屏切换等各种状态

一.MethodChannel

1.flutter 端代码


  • 创建 MethodChannel 交互通道

  • 接收 ohos 端传递过来状态


 class OrientationPlugin {  static const _methodChannel =      const MethodChannel('sososdk.github.com/orientation');
static const _eventChannel = const EventChannel('sososdk.github.com/orientationEvent');
/// see [SystemChrome.setEnabledSystemUIOverlays] static Future<void> setEnabledSystemUIOverlays( List<SystemUiOverlay> overlays) async { if (Platform.isAndroid) { await _methodChannel.invokeMethod<void>( 'SystemChrome.setEnabledSystemUIOverlays', _stringify(overlays), ); } else { SystemChrome.setEnabledSystemUIOverlays(overlays); } }
/// see [SystemChrome.setPreferredOrientations] static Future<void> setPreferredOrientations( List<DeviceOrientation> orientations) async { await _methodChannel.invokeMethod<void>( 'SystemChrome.setPreferredOrientations', _stringify(orientations), ); }
/// Force change of orientation static Future<void> forceOrientation(DeviceOrientation orientation) async { await _methodChannel.invokeMethod<void>( 'SystemChrome.forceOrientation', orientation.toString(), ); }
static List<String> _stringify(List<dynamic> list) { final List<String> result = <String>[]; for (dynamic item in list) result.add(item.toString()); return result; }
static Stream<DeviceOrientation>? _onOrientationChange;
static Stream<DeviceOrientation> get onOrientationChange { if (_onOrientationChange == null) { _onOrientationChange = _eventChannel .receiveBroadcastStream() .map((event) => _convert(event)); } return _onOrientationChange!; }
static DeviceOrientation _convert(String value) { if (value == DeviceOrientation.portraitUp.toString()) { return DeviceOrientation.portraitUp; } else if (value == DeviceOrientation.portraitDown.toString()) { return DeviceOrientation.portraitDown; } else if (value == DeviceOrientation.landscapeLeft.toString()) { return DeviceOrientation.landscapeLeft; } else if (value == DeviceOrientation.landscapeRight.toString()) { return DeviceOrientation.landscapeRight; } else { throw FlutterError('Unknow orientation'); } }}
复制代码


2.ohos 端代码


  • 继承 FlutterPlugin 实现 onAttachedToEngine 方法

  • 创建 MethodChannel 实例 video_compress

  • onMethodCall 回调中监听回调方法(名字需要与 flutter 端保持一致)

  • 通过 MethodResult 回传参数


getUniqueClassName(): string {    return "OrientationPlugin";  }
onAttachedToAbility(binding: AbilityPluginBinding): void { Log.i(TAG, "onAttachedToAbility"); this.ability = binding.getAbility() }
onDetachedFromAbility(): void { Log.i(TAG, "onDetachedFromAbility"); this.ability = null; }
private methodChannel: MethodChannel | null = null; private eventChannel: EventChannel | null = null; private applicationContext: Context | null = null; private ability: UIAbility | null = null; private isLayoutFullScreen = false;
orientation(orientation: number) { if (orientation == window.Orientation.PORTRAIT) { return "DeviceOrientation.portraitUp"; } else if (orientation == window.Orientation.PORTRAIT_INVERTED) { return "DeviceOrientation.portraitDown"; } else if (orientation == window.Orientation.LANDSCAPE) { return "DeviceOrientation.landscapeLeft"; } else if (orientation == window.Orientation.LANDSCAPE_INVERTED) { return "DeviceOrientation.landscapeRight"; } else { return null; } }
onAttachedToEngine(binding: FlutterPluginBinding): void { this.applicationContext = binding.getApplicationContext(); this.methodChannel = new MethodChannel(binding.getBinaryMessenger(), "sososdk.github.com/orientation"); this.methodChannel.setMethodCallHandler(this);
// 监听屏幕旋转 this.eventChannel = new EventChannel(binding.getBinaryMessenger(), "sososdk.github.com/orientationEvent"); this.eventChannel.setStreamHandler({ onListen: (args: Object, eventSink: EventSink) => {
sensor.on(sensor.SensorId.ACCELEROMETER, (data: sensor.AccelerometerResponse) => { // Log.i(TAG, `xyz ${data.x} ${data.y} ${data.z}`) let angle = 0; let magnitude = data.x * data.x + data.y * data.y; // Don't trust the angle if the magnitude is small compared to the y value if (magnitude * 4 >= data.z * data.z) { let OneEightyOverPi = 57.29577957855; angle = 90 - Math.round(Math.atan2(-data.y, data.x) * OneEightyOverPi); // normalize to 0 - 359 range while (angle >= 360) { angle -= 360; } while (angle < 0) { angle += 360; } }
this.sendOrientationChange(eventSink, this.convertAngle(angle)) }, { interval: 100000000 });
}, onCancel: () => { sensor.off(sensor.SensorId.ACCELEROMETER); } }); }
private prevOrientation: number | null = null
sendOrientationChange(eventSink: EventSink, orientation: number) { if (this.prevOrientation !== orientation) { this.prevOrientation = orientation; const value = this.orientation(orientation); if (value !== null) { eventSink.success(value); } } }
onDetachedFromEngine(binding: FlutterPluginBinding): void { this.applicationContext = null; this.methodChannel?.setMethodCallHandler(null); this.methodChannel = null; this.eventChannel?.setStreamHandler(null); this.eventChannel = null; }
onMethodCall(call: MethodCall, result: MethodResult): void { try { if (call.method == "SystemChrome.setEnabledSystemUIOverlays") { // this.setSystemChromeEnabledSystemUIOverlays() // result.success(null); // 利用dart实现,无需native实现 result.notImplemented(); } else if (call.method == "SystemChrome.setPreferredOrientations") { this.setSystemChromePreferredOrientations(call.args); result.success(null); } else if (call.method == "SystemChrome.forceOrientation") { this.forceOrientation(call.args); result.success(null); } else { result.notImplemented() } } catch (err) { result.error("Name not found", err.message, null) } }
// setSystemChromeEnabledSystemUIOverlays() { // window.getLastWindow(this.ability?.context).then(windowClass => { // this.isLayoutFullScreen = !this.isLayoutFullScreen; // windowClass.setWindowLayoutFullScreen(this.isLayoutFullScreen, (err: BusinessError) => { // const errCode: number = err.code; // if (errCode) { // console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err)); // return; // } // console.info('Succeeded in setting the window layout to full-screen mode.'); // }); // }) // }
setSystemChromePreferredOrientations(orientations: string[]) { let requestedOrientation = 0x00; for (let index = 0; index < orientations.length; index += 1) { if (orientations[index] === "DeviceOrientation.portraitUp") { requestedOrientation |= 0x01; } else if (orientations[index] === "DeviceOrientation.landscapeLeft") { requestedOrientation |= 0x02; } else if (orientations[index] === "DeviceOrientation.portraitDown") { requestedOrientation |= 0x04; } else if (orientations[index] === "DeviceOrientation.landscapeRight") { requestedOrientation |= 0x08; } } window.getLastWindow(this.ability?.context).then(windowClass => { switch (requestedOrientation) { case 0x00: windowClass.setPreferredOrientation(window.Orientation.UNSPECIFIED); break; case 0x01: windowClass.setPreferredOrientation(window.Orientation.PORTRAIT); break; case 0x02: windowClass.setPreferredOrientation(window.Orientation.LANDSCAPE); break; case 0x04: windowClass.setPreferredOrientation(window.Orientation.PORTRAIT_INVERTED); break; case 0x05: windowClass.setPreferredOrientation(window.Orientation.PORTRAIT); break; case 0x08: windowClass.setPreferredOrientation(window.Orientation.LANDSCAPE_INVERTED); break; case 0x0a: windowClass.setPreferredOrientation(window.Orientation.LANDSCAPE); break; case 0x0b: windowClass.setPreferredOrientation(window.Orientation.AUTO_ROTATION); break; case 0x0f: windowClass.setPreferredOrientation(window.Orientation.AUTO_ROTATION); break; case 0x03: // portraitUp and landscapeLeft case 0x06: // portraitDown and landscapeLeft case 0x07: // portraitUp, portraitDown, and landscapeLeft case 0x09: // portraitUp and landscapeRight case 0x0c: // portraitDown and landscapeRight case 0x0d: // portraitUp, portraitDown, and landscapeRight case 0x0e: // portraitDown, landscapeLeft, and landscapeRight windowClass.setPreferredOrientation(window.Orientation.AUTO_ROTATION); break; } }); }
forceOrientation(orientation: string) { Log.i(TAG, orientation) window.getLastWindow(this.ability?.context).then(windowClass => { if (orientation === "DeviceOrientation.portraitUp") { windowClass.setPreferredOrientation(window.Orientation.PORTRAIT); } else if (orientation === "DeviceOrientation.portraitDown") { windowClass.setPreferredOrientation(window.Orientation.PORTRAIT_INVERTED); } else if (orientation === "DeviceOrientation.landscapeLeft") { windowClass.setPreferredOrientation(window.Orientation.LANDSCAPE_INVERTED); } else if (orientation === "DeviceOrientation.landscapeRight") { windowClass.setPreferredOrientation(window.Orientation.LANDSCAPE); } else { windowClass.setPreferredOrientation(window.Orientation.UNSPECIFIED); } }) }
convertAngle(angle: number) { angle = angle % 360; Log.i(TAG, `angle ${angle}`); if (angle >= 120 && angle <= 240) { return window.Orientation.PORTRAIT; } else if (angle >= 30 && angle <= 150) { return window.Orientation.LANDSCAPE_INVERTED; } else if (angle >= 300 || (angle <= 60 && angle > 0)) { return window.Orientation.PORTRAIT_INVERTED; } else if (angle >= 210 && angle <= 330) { return window.Orientation.LANDSCAPE; } else { return window.Orientation.UNSPECIFIED; } }
复制代码


用户头像

flfljh

关注

还未添加个人签名 2024-10-29 加入

还未添加个人简介

评论

发布
暂无评论
harmony_flutter_orientation_plugins(监听屏幕状态插件)_flfljh_InfoQ写作社区