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