preserve camera controls values after controller dispose

This commit is contained in:
Vadim 2025-04-02 00:00:33 +02:00
parent 79f702f7ea
commit 2e3335e374

View file

@ -26,11 +26,12 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
final LightmeterAnalytics _analytics;
late final _WidgetsBindingObserver _observer;
CameraDescription? _camera;
CameraController? _cameraController;
static const _maxZoom = 7.0;
RangeValues? _zoomRange;
double _currentZoom = 0.0;
double _currentZoom = 1.0;
static const _exposureMaxRange = RangeValues(-4, 4);
RangeValues? _exposureOffsetRange;
@ -116,46 +117,63 @@ class CameraContainerBloc extends EvSourceBlocBase<CameraContainerEvent, CameraC
}
try {
final cameras = await availableCameras();
if (cameras.isEmpty) {
emit(const CameraErrorState(CameraErrorType.noCamerasDetected));
return;
if (_camera == null) {
final cameras = await availableCameras();
if (cameras.isEmpty) {
emit(const CameraErrorState(CameraErrorType.noCamerasDetected));
return;
} else {
_camera = cameras.firstWhere(
(camera) => camera.lensDirection == CameraLensDirection.back,
orElse: () => cameras.last,
);
}
}
_cameraController = CameraController(
cameras.firstWhere(
(camera) => camera.lensDirection == CameraLensDirection.back,
orElse: () => cameras.last,
),
_camera!,
ResolutionPreset.low,
enableAudio: false,
);
await _cameraController!.initialize();
await _cameraController!.setFlashMode(FlashMode.off);
await _cameraController!.lockCaptureOrientation(DeviceOrientation.portraitUp);
_zoomRange = await Future.wait<double>([
_cameraController!.getMinZoomLevel(),
_cameraController!.getMaxZoomLevel(),
]).then((levels) => RangeValues(math.max(1.0, levels[0]), math.min(_maxZoom, levels[1])));
_currentZoom = _zoomRange!.start;
/// For app startup initialization this effectively isn't executed.
await Future.wait<void>([
if (_currentZoom != 1.0) _cameraController!.setZoomLevel(_currentZoom),
if (_currentExposureOffset != 0.0) _cameraController!.setExposureOffset(_currentExposureOffset),
]);
_exposureOffsetRange = await Future.wait<double>([
_cameraController!.getMinExposureOffset(),
_cameraController!.getMaxExposureOffset(),
]).then(
(levels) => RangeValues(
math.max(_exposureMaxRange.start, levels[0]),
math.min(_exposureMaxRange.end, levels[1]),
),
);
await _cameraController!.getExposureOffsetStepSize().then((value) {
_exposureStep = value == 0 ? 0.1 : value;
});
_currentExposureOffset = 0.0;
if (_zoomRange == null) {
await Future.wait<double>([
_cameraController!.getMinZoomLevel(),
_cameraController!.getMaxZoomLevel(),
]).then((value) {
_zoomRange = RangeValues(
math.max(1.0, value[0]),
math.min(_maxZoom, value[1]),
);
_currentZoom = _zoomRange!.start;
});
}
if (_exposureOffsetRange == null) {
await Future.wait<double>([
_cameraController!.getMinExposureOffset(),
_cameraController!.getMaxExposureOffset(),
_cameraController!.getExposureOffsetStepSize(),
]).then((value) {
_exposureOffsetRange = RangeValues(
math.max(_exposureMaxRange.start, value[0]),
math.min(_exposureMaxRange.end, value[1]),
);
_currentExposureOffset = 0.0;
_exposureStep = value[2] == 0 ? 0.1 : value[2];
});
}
emit(CameraInitializedState(_cameraController!));
_emitActiveState(emit);
} catch (e) {
emit(const CameraErrorState(CameraErrorType.other));