@@ -153,7 +153,6 @@ class CameraPickerState extends State<CameraPicker>
153
153
/// 当前相机实例的控制器
154
154
CameraController get controller => _controller! ;
155
155
CameraController ? _controller;
156
- bool _shouldLockInitialize = false ;
157
156
158
157
/// Available cameras.
159
158
/// 可用的相机实例
@@ -318,10 +317,7 @@ class CameraPickerState extends State<CameraPicker>
318
317
}
319
318
if (state == AppLifecycleState .inactive) {
320
319
c.dispose ();
321
- } else if (state == AppLifecycleState .resumed && ! _shouldLockInitialize) {
322
- // Drop initialize when the controller has been already initialized.
323
- // This will typically resolve the lifecycle issue on iOS when permissions
324
- // are requested for the first time.
320
+ } else if (state == AppLifecycleState .resumed) {
325
321
initCameras (currentCamera);
326
322
}
327
323
}
@@ -352,17 +348,20 @@ class CameraPickerState extends State<CameraPicker>
352
348
353
349
/// Initialize cameras instances.
354
350
/// 初始化相机实例
355
- void initCameras ([CameraDescription ? cameraDescription]) {
351
+ Future < void > initCameras ([CameraDescription ? cameraDescription]) async {
356
352
// Save the current controller to a local variable.
357
353
final CameraController ? c = _controller;
358
- // Then unbind the controller from widgets, which requires a build frame.
354
+ // Dispose at last to avoid disposed usage with assertions.
355
+ if (c != null ) {
356
+ _controller = null ;
357
+ await c.dispose ();
358
+ }
359
+ // Then request a new frame to unbind the controller from elements.
359
360
safeSetState (() {
360
- _shouldLockInitialize = true ;
361
361
_maxAvailableZoom = 1 ;
362
362
_minAvailableZoom = 1 ;
363
363
_currentZoom = 1 ;
364
364
_baseZoom = 1 ;
365
- _controller = null ;
366
365
// Meanwhile, cancel the existed exposure point and mode display.
367
366
_exposureModeDisplayTimer? .cancel ();
368
367
_exposurePointDisplayTimer? .cancel ();
@@ -374,9 +373,6 @@ class CameraPickerState extends State<CameraPicker>
374
373
// **IMPORTANT**: Push methods into a post frame callback, which ensures the
375
374
// controller has already unbind from widgets.
376
375
useWidgetsBinding ().addPostFrameCallback ((_) async {
377
- // Dispose at last to avoid disposed usage with assertions.
378
- await c? .dispose ();
379
-
380
376
// When the [cameraDescription] is null, which means this is the first
381
377
// time initializing cameras, so available cameras should be fetched.
382
378
if (cameraDescription == null ) {
@@ -386,7 +382,6 @@ class CameraPickerState extends State<CameraPicker>
386
382
// After cameras fetched, judge again with the list is empty or not to
387
383
// ensure there is at least an available camera for use.
388
384
if (cameraDescription == null && (cameras.isEmpty)) {
389
- _shouldLockInitialize = false ;
390
385
handleErrorWithHandler (
391
386
CameraException (
392
387
'No CameraDescription found.' ,
@@ -408,49 +403,37 @@ class CameraPickerState extends State<CameraPicker>
408
403
index = currentCameraIndex;
409
404
}
410
405
// Initialize the controller with the given resolution preset.
411
- _controller = CameraController (
406
+ final CameraController newController = CameraController (
412
407
cameraDescription ?? cameras[index],
413
408
config.resolutionPreset,
414
409
enableAudio: enableAudio,
415
410
imageFormatGroup: config.imageFormatGroup,
416
- )..addListener (() {
417
- if (controller.value.hasError) {
418
- handleErrorWithHandler (
419
- CameraException (
420
- 'CameraController exception' ,
421
- controller.value.errorDescription,
422
- ),
423
- config.onError,
424
- );
425
- }
426
- });
411
+ );
427
412
428
413
try {
429
- await controller.initialize ();
430
- safeSetState (() {});
414
+ await newController.initialize ();
431
415
// Call recording preparation first.
432
416
if (shouldPrepareForVideoRecording) {
433
- await controller .prepareForVideoRecording ();
417
+ await newController .prepareForVideoRecording ();
434
418
}
435
419
// Then call other asynchronous methods.
436
420
await Future .wait (< Future <void >> [
437
421
if (config.lockCaptureOrientation != null )
438
- controller .lockCaptureOrientation (config.lockCaptureOrientation),
422
+ newController .lockCaptureOrientation (config.lockCaptureOrientation),
439
423
(() async => _maxAvailableExposureOffset =
440
- await controller .getMaxExposureOffset ())(),
424
+ await newController .getMaxExposureOffset ())(),
441
425
(() async => _minAvailableExposureOffset =
442
- await controller .getMinExposureOffset ())(),
426
+ await newController .getMinExposureOffset ())(),
443
427
(() async =>
444
- _maxAvailableZoom = await controller .getMaxZoomLevel ())(),
428
+ _maxAvailableZoom = await newController .getMaxZoomLevel ())(),
445
429
(() async =>
446
- _minAvailableZoom = await controller .getMinZoomLevel ())(),
430
+ _minAvailableZoom = await newController .getMinZoomLevel ())(),
447
431
]);
432
+ _controller = newController;
448
433
} catch (e, s) {
449
434
handleErrorWithHandler (e, config.onError, s: s);
450
435
} finally {
451
- safeSetState (() {
452
- _shouldLockInitialize = false ;
453
- });
436
+ safeSetState (() {});
454
437
}
455
438
});
456
439
}
0 commit comments