You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter手电筒开发:如何根据状态切换显示开关图标?

解决Flutter手电筒开关按钮切换显示问题

核心修改思路

  • 将TorchController从StatelessWidget改为StatefulWidget,用于维护手电筒的开启状态
  • 添加状态变量bool _isTorchOn = false,记录当前手电筒是否处于开启状态
  • 将开关按钮移至AppBar的actions区域,根据_isTorchOn的值动态切换按钮图标与功能
  • 在手电筒开关操作完成后,调用setState()触发UI刷新,确保按钮状态与实际手电筒状态一致

修改后的完整代码

class TorchController extends StatefulWidget {
  const TorchController({super.key});

  @override
  State<TorchController> createState() => _TorchControllerState();
}

class _TorchControllerState extends State<TorchController> {
  bool _isTorchOn = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('手电筒'),
        actions: [
          IconButton(
            icon: Icon(
              _isTorchOn ? Icons.flashlight_off_outlined : Icons.flashlight_on_outlined,
              size: 35,
            ),
            onPressed: () async {
              if (_isTorchOn) {
                await _disableTorch(context);
              } else {
                await _enableTorch(context);
              }
              setState(() {
                _isTorchOn = !_isTorchOn;
              });
            },
          ),
        ],
      ),
      body: FutureBuilder<bool>(
        future: _isTorchAvailable(context),
        builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
          if (snapshot.hasData && snapshot.data!) {
            return const Center(
              child: Text('手电筒已就绪'),
            );
          } else if (snapshot.hasData) {
            return const Center(
              child: Text('当前设备无可用手电筒'),
            );
          } else {
            return const Center(
              child: CircularProgressIndicator(),
            );
          }
        },
      ),
    );
  }

  Future<bool> _isTorchAvailable(BuildContext context) async {
    try {
      return await TorchLight.isTorchAvailable();
    } on Exception catch (_) {
      _showMessage('无法检测设备是否有可用手电筒', context);
      rethrow;
    }
  }

  Future<void> _enableTorch(BuildContext context) async {
    try {
      await TorchLight.enableTorch();
    } on Exception catch (_) {
      _showMessage('无法开启手电筒', context);
      setState(() {
        _isTorchOn = false;
      });
    }
  }

  Future<void> _disableTorch(BuildContext context) async {
    try {
      await TorchLight.disableTorch();
    } on Exception catch (_) {
      _showMessage('无法关闭手电筒', context);
      setState(() {
        _isTorchOn = true;
      });
    }
  }

  void _showMessage(String message, BuildContext context) {
    ScaffoldMessenger.of(context)
        .showSnackBar(SnackBar(content: Text(message)));
  }
}

关键细节说明

  • 合并开关按钮为一个,通过状态变量动态切换图标,避免同时显示两个按钮
  • 在异常处理中增加状态回滚逻辑,确保UI状态与实际手电筒操作结果一致
  • 将按钮移至AppBar的actions区域,符合你要求的开关按钮位置

内容的提问来源于stack exchange,提问作者datavinnie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 00:55:05