@@ -57,8 +57,8 @@ class CameraPickerState extends State<CameraPicker>
57
57
/// 可用的相机实例
58
58
late List <CameraDescription > cameras;
59
59
60
- /// Whether the controller is handling taking picture or recording video .
61
- /// 相机控制器是否在处理拍照或录像
60
+ /// Whether the controller is handling method calls .
61
+ /// 相机控制器是否在处理方法调用
62
62
bool isControllerBusy = false ;
63
63
64
64
/// Current exposure offset.
@@ -186,6 +186,12 @@ class CameraPickerState extends State<CameraPicker>
186
186
return pickerConfig.minimumRecordingDuration;
187
187
}
188
188
189
+ /// Whether the capture button is displaying.
190
+ bool get shouldCaptureButtonDisplay =>
191
+ isControllerBusy ||
192
+ (innerController? .value.isRecordingVideo ?? false ) &&
193
+ isRecordingRestricted;
194
+
189
195
/// Whether the camera preview should be rotated.
190
196
bool get isCameraRotated => pickerConfig.cameraQuarterTurns % 4 != 0 ;
191
197
@@ -258,15 +264,19 @@ class CameraPickerState extends State<CameraPicker>
258
264
} else if (state == AppLifecycleState .inactive) {
259
265
c.dispose ();
260
266
innerController = null ;
267
+ isControllerBusy = false ;
261
268
}
262
269
}
263
270
264
271
/// Adjust the proper scale type according to the [constraints] .
265
272
/// 根据 [constraints] 获取相机预览适用的缩放。
266
273
double effectiveCameraScale (
267
274
BoxConstraints constraints,
268
- CameraController controller,
275
+ CameraController ? controller,
269
276
) {
277
+ if (controller == null ) {
278
+ return 1 ;
279
+ }
270
280
final int turns = cameraQuarterTurns;
271
281
final String orientation = controller.value.deviceOrientation.toString ();
272
282
// Fetch the biggest size from the constraints.
@@ -831,7 +841,10 @@ class CameraPickerState extends State<CameraPicker>
831
841
if (isControllerBusy) {
832
842
return ;
833
843
}
834
- isControllerBusy = true ;
844
+ setState (() {
845
+ isControllerBusy = true ;
846
+ isShootingButtonAnimate = true ;
847
+ });
835
848
final ExposureMode previousExposureMode = controller.value.exposureMode;
836
849
try {
837
850
await Future .wait (< Future <void >> [
@@ -881,8 +894,10 @@ class CameraPickerState extends State<CameraPicker>
881
894
} catch (e, s) {
882
895
handleErrorWithHandler (e, s, pickerConfig.onError);
883
896
} finally {
884
- isControllerBusy = false ;
885
- safeSetState (() {});
897
+ safeSetState (() {
898
+ isControllerBusy = false ;
899
+ isShootingButtonAnimate = false ;
900
+ });
886
901
}
887
902
}
888
903
@@ -909,14 +924,7 @@ class CameraPickerState extends State<CameraPicker>
909
924
/// 将被取消,并且状态会重置。
910
925
void recordDetectionCancel (PointerUpEvent event) {
911
926
recordDetectTimer? .cancel ();
912
- if (isShootingButtonAnimate) {
913
- safeSetState (() {
914
- isShootingButtonAnimate = false ;
915
- });
916
- }
917
927
if (innerController? .value.isRecordingVideo == true ) {
918
- lastShootingButtonPressedPosition = null ;
919
- safeSetState (() {});
920
928
stopRecordingVideo ();
921
929
}
922
930
}
@@ -940,7 +948,6 @@ class CameraPickerState extends State<CameraPicker>
940
948
..reset ()
941
949
..start ();
942
950
} catch (e, s) {
943
- isControllerBusy = false ;
944
951
if (! controller.value.isRecordingVideo) {
945
952
handleErrorWithHandler (e, s, pickerConfig.onError);
946
953
return ;
@@ -955,34 +962,39 @@ class CameraPickerState extends State<CameraPicker>
955
962
recordStopwatch.stop ();
956
963
}
957
964
} finally {
958
- safeSetState (() {});
965
+ safeSetState (() {
966
+ isControllerBusy = false ;
967
+ });
959
968
}
960
969
}
961
970
962
971
/// Stop the recording process.
963
972
/// 停止录制视频
964
973
Future <void > stopRecordingVideo () async {
965
- void handleError () {
966
- recordCountdownTimer? .cancel ();
967
- isShootingButtonAnimate = false ;
968
- safeSetState (() {});
974
+ if (isControllerBusy) {
975
+ return ;
969
976
}
970
977
971
978
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
+ });
974
985
return ;
975
986
}
976
987
safeSetState (() {
977
- isShootingButtonAnimate = false ;
988
+ isControllerBusy = true ;
989
+ lastShootingButtonPressedPosition = null ;
978
990
});
979
991
try {
980
992
final XFile file = await controller.stopVideoRecording ();
981
993
if (recordStopwatch.elapsed < minimumRecordingDuration) {
982
994
pickerConfig.onMinimumRecordDurationNotMet? .call ();
983
995
return ;
984
996
}
985
- await controller.pausePreview ();
997
+ controller.pausePreview ();
986
998
final bool ? isCapturedFileHandled = pickerConfig.onXFileCaptured? .call (
987
999
file,
988
1000
CameraPickerViewType .video,
@@ -1000,12 +1012,14 @@ class CameraPickerState extends State<CameraPicker>
1000
1012
await controller.resumePreview ();
1001
1013
}
1002
1014
} catch (e, s) {
1003
- handleError ();
1015
+ recordCountdownTimer ? . cancel ();
1004
1016
initCameras ();
1005
1017
handleErrorWithHandler (e, s, pickerConfig.onError);
1006
1018
} finally {
1007
- isControllerBusy = false ;
1008
- safeSetState (() {});
1019
+ safeSetState (() {
1020
+ isControllerBusy = false ;
1021
+ isShootingButtonAnimate = false ;
1022
+ });
1009
1023
}
1010
1024
}
1011
1025
@@ -1319,17 +1333,17 @@ class CameraPickerState extends State<CameraPicker>
1319
1333
),
1320
1334
),
1321
1335
),
1322
- if ((innerController? .value.isRecordingVideo ?? false ) &&
1323
- isRecordingRestricted)
1336
+ if (shouldCaptureButtonDisplay)
1324
1337
RotatedBox (
1325
1338
quarterTurns:
1326
1339
! enableScaledPreview ? cameraQuarterTurns : 0 ,
1327
1340
child: CameraProgressButton (
1328
1341
isAnimating: isShootingButtonAnimate,
1342
+ isBusy: isControllerBusy,
1329
1343
duration: pickerConfig.maximumRecordingDuration! ,
1330
- outerRadius : outerSize.width ,
1344
+ size : outerSize,
1331
1345
ringsColor: theme.indicatorColor,
1332
- ringsWidth: 2 ,
1346
+ ringsWidth: 3 ,
1333
1347
),
1334
1348
),
1335
1349
],
@@ -1675,7 +1689,7 @@ class CameraPickerState extends State<CameraPicker>
1675
1689
// Scale the preview if the config is enabled.
1676
1690
if (enableScaledPreview) {
1677
1691
preview = Transform .scale (
1678
- scale: effectiveCameraScale (constraints, controller ),
1692
+ scale: effectiveCameraScale (constraints, innerController ),
1679
1693
child: Center (child: transformedWidget ?? preview),
1680
1694
);
1681
1695
// Rotated the preview if the turns is valid.
0 commit comments