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

Flutter中StreamBuilder返回的RadioListTile点击后无法选中问题

问题原因

  • Dart默认对自定义类的==判断是比对内存引用,你每次从Firestore同步拿到的都是新的Endereco实例,就算所有属性完全相同,默认比对也会返回false,导致RadioListTile无法匹配value和groupValue,就不会显示选中状态。
  • 代码存在类型不匹配隐患:noteStream声明返回List<Address>,但RadioListTile用的是Endereco泛型,且生成地址列表时没有明确指定集合类型,可能触发隐式类型转换导致比对失效。

修复步骤

1. 为Endereco类重载==运算符和hashCode

自定义比对逻辑,用业务唯一标识(比如地址id)或者全量属性判断两个对象是否相等,示例代码:

class Endereco {
  // 你的原有属性
  final String id;
  final String rua;
  final int numero;
  final String complemento;
  final String bairro;
  final String cidade;
  final String estado;
  final String cep;

  Endereco({
    required this.id,
    required this.rua,
    required this.numero,
    required this.complemento,
    required this.bairro,
    required this.cidade,
    required this.estado,
    required this.cep,
  });

  // 重载==
  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Endereco &&
          runtimeType == other.runtimeType &&
          id == other.id; 
  // 没有唯一id就把所有业务属性都加到判断条件里,比如id == other.id && rua == other.rua && numero == other.numero ...

  // 对应重载hashCode
  @override
  int get hashCode => id.hashCode; 
  // 用了哪些属性判断==,就把这些属性的hashCode组合起来,比如id.hashCode ^ rua.hashCode ^ numero.hashCode ...

  // 你的原有fromDocumentSnapshot方法
  factory Endereco.fromDocumentSnapshot({required DocumentSnapshot<Map<String,dynamic>> doc}) {
    final data = doc.data()!;
    return Endereco(
      id: doc.id,
      rua: data['rua'],
      numero: data['numero'],
      complemento: data['complemento'],
      bairro: data['bairro'],
      cidade: data['cidade'],
      estado: data['estado'],
      cep: data['cep'],
    );
  }
}

2. 修正noteStream的类型匹配

把noteStream的返回类型和集合类型统一为Endereco,避免类型隐式转换:

Stream<List<Endereco>> noteStream(String uid){
  try{
    return _db.collection("users").doc(uid).collection("address").snapshots().map((address){
      final List<Endereco> addressFromFirestore = [];
      for(final DocumentSnapshot<Map<String,dynamic>> doc in address.docs){
        addressFromFirestore.add(Endereco.fromDocumentSnapshot(doc: doc));
      }
      return addressFromFirestore;
    });
  }catch(e){
    rethrow;
  }
}

3. 可选优化

RadioListTile默认会自动比对value和groupValue判断是否选中,不需要额外设置selected属性,可去掉这行代码减少冗余。

内容的提问来源于stack exchange,提问作者João César Rodrigues Ferreira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 14:45:00