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

Flutter中Provider三元运算符判断始终返回False问题求助

问题:三元判断始终返回'Blackout',即使blackoutStatus[1]显示为'0'

预期Text组件在RxStatus Provider的blackoutStatus[1]值为'0'时显示Normal,其他值显示Blackout,但实际无论该值显示为'0'还是'2',三元判断始终返回Blackout。已通过额外Text组件确认blackoutStatus[1]确实在'0'和'2'之间切换,但判断逻辑不生效。

相关代码

问题代码片段

Container(
  child: Text(
    Provider.of<RxStatus>(context,listen:true).blackoutStatus[int.parse('1')] == '0' ? 'Normal':'BlackOut',
    style: TextStyle(color: Colors.red),
  ),
)

Vault组件核心代码

class Vault extends StatefulWidget {
  const Vault({Key? key}) : super(key: key);

  @override
  _VaultState createState() => _VaultState();
}

class _VaultState extends State<Vault> {
  late Timer _timer;

  @override
  initState() {
    _timer = Timer.periodic(const Duration(seconds: 5), (timer) {
      Provider.of<RxStatus>(context,listen: false).getFeedback("vault");
      print('vault');
    });
    print("vault initState Called");
  }

  void dispose() {
    print('dispose vault');
    _timer?.cancel();
    super.dispose();
  }

  Widget build(BuildContext context) {
    var screenSize = MediaQuery.of(context).size;

    return Stack(
      children:[ 
        Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            //Right Wall
            Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                RotatedBox(quarterTurns:1 , child: ProDsxRx(rxLabel: 'Vault 7', rxId: '7')),
                RotatedBox(quarterTurns:1 , child: ProDsxRx(rxLabel: 'Vault 8', rxId: '8')),
                RotatedBox(quarterTurns:1 , child: ProDsxRx(rxLabel: 'Vault 9', rxId: '9')),
                Container(
                  child: Text(
                    Provider.of<RxStatus>(context,listen: true).blackoutStatus[int.parse('1')] ,
                    style: TextStyle(color: Colors.red),
                  ),
                ),
                Container(
                  child: Text(
                    Provider.of<RxStatus>(context,listen: true).blackoutStatus[int.parse('1')] == '0' ? 'Normal': 'BlackOut',
                    style: TextStyle(color: Colors.red),
                  ),
                )
              ],
            )
          ],
        ),
        ProdsxFloatingMenuButton()
      ],
    );
  }
}

RxStatus Provider核心代码

class RxStatus extends ChangeNotifier {
  List rxIDs = [
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,13, 14, 15, 16, 19, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46
  ];

  final List rxIDs_bank = [
    10, 11, 12,13, 14, 15,19, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46
  ];

  final List rxIDs_vault = [
    1, 2, 3, 4, 5, 6, 7, 8, 9,16,
  ];
 
  Map blackoutStatus = {
    1:'0',2:'0',3:'0',4:'0',5:'0',
    6:'0',7:'0',8:'0',9:'0',10:'0',
    11:'0',12:'0',13:'0',14:'0',
    15:'0', 16:'0', 23:'0', 24:'0', 25:'0', 26:'0',
    27:'0', 28:'0', 29:'0', 30:'0', 31:'0', 32:'0',
    33:'0', 34:'0', 35:'0', 36:'0', 37:'0', 38:'0',
    39:'0', 40:'0', 41:'0', 42:'0', 43:'0', 44:'0',
    45:'0', 46:'0',
  };

  getFeedback(_bank_vault) async {
    if(_bank_vault == 'bank'){
      rxIDs = [...rxIDs_bank];
    }else if(_bank_vault =='vault'){
      rxIDs = [...rxIDs_vault];
    }
   
    rxIDs.asMap().forEach((index, item) async {
      try {
        print('blackout status${item}');
        // Check blackout
        var response = await http.get(Uri.parse('http://172.31.3.${item}/cgi-bin/query.cgi?cmd=cat /sys/devices/platform/videoip/pause'));
        blackoutStatus[item] = response.body;
        print(blackoutStatus);
        notifyListeners();
      }catch (error) {
        blackoutStatus[item] = 'Error';
        notifyListeners();
      }
    });
  }
}

问题原因

核心问题是HTTP请求返回的response.body可能包含多余的空白字符(比如换行符\n、空格)。虽然UI显示时看不到这些空白,但字符串严格比较时,'0\n' == '0'会返回false,导致三元判断始终触发Blackout分支。

解决方案

1. 处理HTTP返回值(推荐)

在RxStatus的getFeedback方法中,对response.body调用trim()去除首尾空白字符:

blackoutStatus[item] = response.body.trim();

2. 在判断时处理字符串

如果不想修改Provider逻辑,也可以在UI判断时直接对取值做trim处理,同时优化int.parse('1')为直接使用1:

Container(
  child: Text(
    Provider.of<RxStatus>(context,listen: true).blackoutStatus[1]?.trim() == '0' ? 'Normal': 'BlackOut',
    style: TextStyle(color: Colors.red),
  ),
)

额外优化

原代码中rxIDs.asMap().forEach搭配async会导致多个异步请求同时触发,notifyListeners()被频繁调用。可以改用Future.wait批量处理异步请求,统一更新状态:

getFeedback(_bank_vault) async {
  if(_bank_vault == 'bank'){
    rxIDs = [...rxIDs_bank];
  }else if(_bank_vault =='vault'){
    rxIDs = [...rxIDs_vault];
  }
 
  // 批量处理异步请求
  await Future.wait(rxIDs.map((item) async {
    try {
      print('blackout status${item}');
      var response = await http.get(Uri.parse('http://172.31.3.${item}/cgi-bin/query.cgi?cmd=cat /sys/devices/platform/videoip/pause'));
      blackoutStatus[item] = response.body.trim();
    } catch (error) {
      blackoutStatus[item] = 'Error';
    }
  }));
  // 所有请求完成后统一通知状态更新
  notifyListeners();
}

内容的提问来源于stack exchange,提问作者sou pen su

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 23:02:11