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:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user