@@ -114,6 +114,13 @@ class CameraPickerState extends State<CameraPicker>
114114 /// 但如果录像时间没有限制,定时器将不会起作用。
115115 Timer ? recordCountdownTimer;
116116
117+ /// Initialized with all the flash modes for each camera. If a flash mode is
118+ /// not valid, it is removed from the list.
119+ /// 使用每个相机的所有闪光灯模式进行初始化。
120+ /// 如果闪光灯模式无效,则将其从列表中删除。
121+ final Map <CameraDescription , List <FlashMode >> validFlashModes =
122+ < CameraDescription , List <FlashMode >> {};
123+
117124 ////////////////////////////////////////////////////////////////////////////
118125 ////////////////////////////// Global Getters //////////////////////////////
119126 ////////////////////////////////////////////////////////////////////////////
@@ -272,6 +279,7 @@ class CameraPickerState extends State<CameraPicker>
272279 );
273280 }
274281
282+ initFlashModesForCameras ();
275283 final int preferredIndex = cameras.indexWhere (
276284 (CameraDescription e) =>
277285 e.lensDirection == pickerConfig.preferredLensDirection,
@@ -343,6 +351,24 @@ class CameraPickerState extends State<CameraPicker>
343351 });
344352 }
345353
354+ /// Initializes the flash modes in [validFlashModes] for each
355+ /// [CameraDescription] .
356+ /// 为每个 [CameraDescription] 在 [validFlashModes] 中初始化闪光灯模式。
357+ void initFlashModesForCameras () {
358+ for (final CameraDescription camera in cameras) {
359+ if (! validFlashModes.containsKey (camera)) {
360+ // Mind the order of this list as it has an impact on the switch cycle.
361+ // Do not use FlashMode.values.
362+ validFlashModes[camera] = < FlashMode > [
363+ FlashMode .auto,
364+ FlashMode .always,
365+ FlashMode .torch,
366+ FlashMode .off,
367+ ];
368+ }
369+ }
370+ }
371+
346372 /// Switch cameras in order. When the [currentCameraIndex] reached the length
347373 /// of cameras, start from the beginning.
348374 /// 按顺序切换相机。当达到相机数量时从头开始。
@@ -369,25 +395,33 @@ class CameraPickerState extends State<CameraPicker>
369395
370396 /// The method to switch between flash modes.
371397 /// 切换闪光灯模式的方法
372- Future <void > switchFlashesMode () async {
373- final FlashMode newFlashMode;
374- switch (controller.value.flashMode) {
375- case FlashMode .off:
376- newFlashMode = FlashMode .auto;
377- break ;
378- case FlashMode .auto:
379- newFlashMode = FlashMode .always;
380- break ;
381- case FlashMode .always:
382- newFlashMode = FlashMode .torch;
383- break ;
384- case FlashMode .torch:
385- newFlashMode = FlashMode .off;
386- break ;
398+ Future <void > switchFlashesMode (CameraValue value) async {
399+ final List <FlashMode > flashModes = validFlashModes[currentCamera]! ;
400+ if (flashModes.isEmpty) {
401+ // Unlikely event that no flash mode is valid for current camera.
402+ handleErrorWithHandler (
403+ CameraException (
404+ 'No FlashMode found.' ,
405+ 'No flash modes are available with the camera.' ,
406+ ),
407+ pickerConfig.onError,
408+ );
409+ return ;
410+ }
411+ final int currentFlashModeIndex = flashModes.indexOf (value.flashMode);
412+ final int nextFlashModeIndex;
413+ if (currentFlashModeIndex + 1 >= flashModes.length) {
414+ nextFlashModeIndex = 0 ;
415+ } else {
416+ nextFlashModeIndex = currentFlashModeIndex + 1 ;
387417 }
418+ final FlashMode nextFlashMode = flashModes[nextFlashModeIndex];
388419 try {
389- await controller.setFlashMode (newFlashMode );
420+ await controller.setFlashMode (nextFlashMode );
390421 } catch (e, s) {
422+ // Remove the flash mode that throws an exception.
423+ validFlashModes[currentCamera]! .remove (nextFlashMode);
424+ switchFlashesMode (value);
391425 handleErrorWithHandler (e, pickerConfig.onError, s: s);
392426 }
393427 }
@@ -863,7 +897,7 @@ class CameraPickerState extends State<CameraPicker>
863897 break ;
864898 }
865899 return IconButton (
866- onPressed: switchFlashesMode,
900+ onPressed: () => switchFlashesMode (value) ,
867901 tooltip: textDelegate.sFlashModeLabel (value.flashMode),
868902 icon: Icon (icon, size: 24 ),
869903 );
0 commit comments