@@ -57,8 +57,8 @@ class CameraPickerState extends State<CameraPicker>
5757 /// 可用的相机实例
5858 late 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+ /// 相机控制器是否在处理方法调用
6262 bool 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.
190196 bool 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] 获取相机预览适用的缩放。
266273 double 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 /// 将被取消,并且状态会重置。
910925 void 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 /// 停止录制视频
964973 Future <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