sensor: expose orientationListenable as a ValueListenable

Backed by a Dart-side 100ms poll of the existing FFI getter; the polling
timer starts on first listener and stops when the last listener detaches.
This commit is contained in:
agra
2026-05-09 09:04:40 +03:00
parent fb00e98681
commit 65c7a3195a

View File

@@ -1,6 +1,8 @@
import 'dart:async';
import 'dart:ffi';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
DynamicLibrary? _initLib() {
@@ -34,4 +36,47 @@ class UxSensor {
}
return DeviceOrientation.values[idx];
}
/// Lazily-created listenable backing [orientationListenable].
static _OrientationNotifier? _orientationNotifier;
/// Listenable form of [orientation], updated as the device rotates.
/// Backed by a Dart-side 100ms poll of the underlying FFI getter.
static ValueListenable<DeviceOrientation> get orientationListenable {
return _orientationNotifier ??= _OrientationNotifier();
}
}
class _OrientationNotifier extends ChangeNotifier
implements ValueListenable<DeviceOrientation> {
_OrientationNotifier() : _value = UxSensor.orientation;
Timer? _timer;
DeviceOrientation _value;
@override
DeviceOrientation get value => _value;
@override
void addListener(VoidCallback listener) {
super.addListener(listener);
_timer ??= Timer.periodic(const Duration(milliseconds: 100), _tick);
}
@override
void removeListener(VoidCallback listener) {
super.removeListener(listener);
if (!hasListeners) {
_timer?.cancel();
_timer = null;
}
}
void _tick(Timer _) {
final next = UxSensor.orientation;
if (next != _value) {
_value = next;
notifyListeners();
}
}
}