@@ -57,8 +57,8 @@ class CameraPickerState extends State<CameraPicker>
5757  /// 可用的相机实例 
5858late  List <CameraDescription > cameras;
5959
60-   /// Whether the controller is handling taking picture or recording video . 
61-   /// 相机控制器是否在处理拍照或录像  
60+   /// Whether the controller is handling method calls . 
61+   /// 相机控制器是否在处理方法调用  
6262bool  isControllerBusy =  false ;
6363
6464  /// Current exposure offset. 
@@ -186,6 +186,12 @@ class CameraPickerState extends State<CameraPicker>
186186    return  pickerConfig.minimumRecordingDuration;
187187  }
188188
189+   /// Whether the capture button is displaying. 
190+ bool  get  shouldCaptureButtonDisplay => 
191+       isControllerBusy || 
192+       (innerController? .value.isRecordingVideo ??  false ) && 
193+           isRecordingRestricted;
194+ 
189195  /// Whether the camera preview should be rotated. 
190196bool  get  isCameraRotated =>  pickerConfig.cameraQuarterTurns %  4  !=  0 ;
191197
@@ -258,15 +264,19 @@ class CameraPickerState extends State<CameraPicker>
258264    } else  if  (state ==  AppLifecycleState .inactive) {
259265      c.dispose ();
260266      innerController =  null ;
267+       isControllerBusy =  false ;
261268    }
262269  }
263270
264271  /// Adjust the proper scale type according to the [constraints] . 
265272  /// 根据 [constraints]  获取相机预览适用的缩放。 
266273double  effectiveCameraScale (
267274    BoxConstraints  constraints,
268-     CameraController  controller,
275+     CameraController ?  controller,
269276  ) {
277+     if  (controller ==  null ) {
278+       return  1 ;
279+     }
270280    final  int  turns =  cameraQuarterTurns;
271281    final  String  orientation =  controller.value.deviceOrientation.toString ();
272282    // Fetch the biggest size from the constraints. 
@@ -831,7 +841,10 @@ class CameraPickerState extends State<CameraPicker>
831841    if  (isControllerBusy) {
832842      return ;
833843    }
834-     isControllerBusy =  true ;
844+     setState (() {
845+       isControllerBusy =  true ;
846+       isShootingButtonAnimate =  true ;
847+     });
835848    final  ExposureMode  previousExposureMode =  controller.value.exposureMode;
836849    try  {
837850      await  Future .wait (< Future <void >> [
@@ -881,8 +894,10 @@ class CameraPickerState extends State<CameraPicker>
881894    } catch  (e, s) {
882895      handleErrorWithHandler (e, s, pickerConfig.onError);
883896    } finally  {
884-       isControllerBusy =  false ;
885-       safeSetState (() {});
897+       safeSetState (() {
898+         isControllerBusy =  false ;
899+         isShootingButtonAnimate =  false ;
900+       });
886901    }
887902  }
888903
@@ -909,14 +924,7 @@ class CameraPickerState extends State<CameraPicker>
909924  /// 将被取消,并且状态会重置。 
910925void  recordDetectionCancel (PointerUpEvent  event) {
911926    recordDetectTimer? .cancel ();
912-     if  (isShootingButtonAnimate) {
913-       safeSetState (() {
914-         isShootingButtonAnimate =  false ;
915-       });
916-     }
917927    if  (innerController? .value.isRecordingVideo ==  true ) {
918-       lastShootingButtonPressedPosition =  null ;
919-       safeSetState (() {});
920928      stopRecordingVideo ();
921929    }
922930  }
@@ -940,7 +948,6 @@ class CameraPickerState extends State<CameraPicker>
940948        ..reset ()
941949        ..start ();
942950    } catch  (e, s) {
943-       isControllerBusy =  false ;
944951      if  (! controller.value.isRecordingVideo) {
945952        handleErrorWithHandler (e, s, pickerConfig.onError);
946953        return ;
@@ -955,34 +962,39 @@ class CameraPickerState extends State<CameraPicker>
955962        recordStopwatch.stop ();
956963      }
957964    } finally  {
958-       safeSetState (() {});
965+       safeSetState (() {
966+         isControllerBusy =  false ;
967+       });
959968    }
960969  }
961970
962971  /// Stop the recording process. 
963972  /// 停止录制视频 
964973Future <void > stopRecordingVideo () async  {
965-     void  handleError () {
966-       recordCountdownTimer? .cancel ();
967-       isShootingButtonAnimate =  false ;
968-       safeSetState (() {});
974+     if  (isControllerBusy) {
975+       return ;
969976    }
970977
971978    recordStopwatch.stop ();
972-     if  (! controller.value.isRecordingVideo) {
973-       handleError ();
979+     if  (innerController ==  null  ||  ! controller.value.isRecordingVideo) {
980+       recordCountdownTimer? .cancel ();
981+       safeSetState (() {
982+         isControllerBusy =  false ;
983+         isShootingButtonAnimate =  false ;
984+       });
974985      return ;
975986    }
976987    safeSetState (() {
977-       isShootingButtonAnimate =  false ;
988+       isControllerBusy =  true ;
989+       lastShootingButtonPressedPosition =  null ;
978990    });
979991    try  {
980992      final  XFile  file =  await  controller.stopVideoRecording ();
981993      if  (recordStopwatch.elapsed <  minimumRecordingDuration) {
982994        pickerConfig.onMinimumRecordDurationNotMet? .call ();
983995        return ;
984996      }
985-       await   controller.pausePreview ();
997+       controller.pausePreview ();
986998      final  bool ?  isCapturedFileHandled =  pickerConfig.onXFileCaptured? .call (
987999        file,
9881000        CameraPickerViewType .video,
@@ -1000,12 +1012,14 @@ class CameraPickerState extends State<CameraPicker>
10001012        await  controller.resumePreview ();
10011013      }
10021014    } catch  (e, s) {
1003-       handleError ();
1015+       recordCountdownTimer ? . cancel ();
10041016      initCameras ();
10051017      handleErrorWithHandler (e, s, pickerConfig.onError);
10061018    } finally  {
1007-       isControllerBusy =  false ;
1008-       safeSetState (() {});
1019+       safeSetState (() {
1020+         isControllerBusy =  false ;
1021+         isShootingButtonAnimate =  false ;
1022+       });
10091023    }
10101024  }
10111025
@@ -1319,17 +1333,17 @@ class CameraPickerState extends State<CameraPicker>
13191333                      ),
13201334                    ),
13211335                  ),
1322-                   if  ((innerController? .value.isRecordingVideo ??  false ) && 
1323-                       isRecordingRestricted)
1336+                   if  (shouldCaptureButtonDisplay)
13241337                    RotatedBox (
13251338                      quarterTurns: 
13261339                          ! enableScaledPreview ?  cameraQuarterTurns :  0 ,
13271340                      child:  CameraProgressButton (
13281341                        isAnimating:  isShootingButtonAnimate,
1342+                         isBusy:  isControllerBusy,
13291343                        duration:  pickerConfig.maximumRecordingDuration! ,
1330-                         outerRadius :  outerSize.width ,
1344+                         size :  outerSize,
13311345                        ringsColor:  theme.indicatorColor,
1332-                         ringsWidth:  2 ,
1346+                         ringsWidth:  3 ,
13331347                      ),
13341348                    ),
13351349                ],
@@ -1675,7 +1689,7 @@ class CameraPickerState extends State<CameraPicker>
16751689    // Scale the preview if the config is enabled. 
16761690    if  (enableScaledPreview) {
16771691      preview =  Transform .scale (
1678-         scale:  effectiveCameraScale (constraints, controller ),
1692+         scale:  effectiveCameraScale (constraints, innerController ),
16791693        child:  Center (child:  transformedWidget ??  preview),
16801694      );
16811695      // Rotated the preview if the turns is valid. 
0 commit comments