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

Flutter中无法通过变量更新ChoiceChip标签的问题求助

问题描述

我在Widget中展示ChoiceChip,希望通过切换语言时会变化的变量修改Chip的文本标签,但由于列表是静态的,标签无法更新。删除static关键字后,首页出现错误:

List<ChoiceChipData> choiceChips = ChoiceChips.all;

错误提示:

Instance member 'all' can't be accessed using static access.

展示Chip的代码:

choiceChips
          .map((choiceChip) => ChoiceChip(
                labelPadding: const EdgeInsets.only(top: -1, bottom: -1),
                label: Text(choiceChip.label),
                labelStyle: const TextStyle(
                    fontWeight: FontWeight.bold,
                    color: Colors.white,
                    fontSize: 10),
                onSelected: (isSelected) => setState(() {
                  choiceChips = choiceChips.map((otherChip) {
                    final newChip = otherChip.copy(
                      isSelected: false,
                    );

                    return choiceChip == newChip
                        ? newChip.copy(isSelected: isSelected)
                        : newChip;
                  }).toList();

                  choice = choiceChip.value;
                }),
                selected: choiceChip.isSelected,
                selectedColor: const Color(0xFFFAA5A1),
                backgroundColor: const Color.fromARGB(255, 39, 38, 38),
              ))
          .toList(),

choicechips.dart代码:

class ChoiceChips {
  static var all = <ChoiceChipData>[
    ChoiceChipData(
      label: '$vtmnts',
      value: 'Vetement',
      isSelected: false,
      selectedColor: const Color.fromARGB(255, 129, 133, 136),
      textColor: Colors.white,
    ),
    ChoiceChipData(
      label: '$Nourriture',
      value: 'Nourriture',
      isSelected: false,
      selectedColor: Colors.blue,
      textColor: Colors.white,
    ),
  ];
}

ChoiceChipData类代码:

class ChoiceChipData {
  var label;
  final String value;
  final bool isSelected;
  Color textColor;
  Color selectedColor;

  ChoiceChipData({
    required this.label,
    required this.value,
    required this.isSelected,
    required this.textColor,
    required this.selectedColor,
  });

  ChoiceChipData copy({
    String? label,
    String? value,
    bool? isSelected,
    Color? textColor,
    Color? selectedColor,
  }) =>
      ChoiceChipData(
        label: label ?? this.label,
        value: value ?? this.value,
        isSelected: isSelected ?? this.isSelected,
        textColor: textColor ?? this.textColor,
        selectedColor: selectedColor ?? this.selectedColor,
      );

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is ChoiceChipData &&
          runtimeType == other.runtimeType &&
          label == other.label &&
          value == other.value &&
          isSelected == other.isSelected &&
          textColor == other.textColor &&
          selectedColor == other.selectedColor;

  @override
  int get hashCode =>
      label.hashCode ^
      value.hashCode ^
      isSelected.hashCode ^
      textColor.hashCode ^
      selectedColor.hashCode;
}
解决方案

1. 重构ChoiceChips类,用实例属性替代静态列表

静态列表只会在类加载时初始化一次,语言切换时无法更新标签文本。把static all改成实例的getter方法,确保每次获取列表时都会使用最新的本地化变量:

class ChoiceChips {
  List<ChoiceChipData> get all => [
    ChoiceChipData(
      label: '$vtmnts',
      value: 'Vetement',
      isSelected: false,
      selectedColor: const Color.fromARGB(255, 129, 133, 136),
      textColor: Colors.white,
    ),
    ChoiceChipData(
      label: '$Nourriture',
      value: 'Nourriture',
      isSelected: false,
      selectedColor: Colors.blue,
      textColor: Colors.white,
    ),
  ];
}

2. 在Widget中正确初始化列表

在State类中创建ChoiceChips实例,初始化时获取列表,并在语言变化时重新获取(保留选中状态):

class _YourWidgetState extends State<YourWidget> {
  late ChoiceChips _choiceChips;
  late List<ChoiceChipData> choiceChips;
  String? choice;

  @override
  void initState() {
    super.initState();
    _choiceChips = ChoiceChips();
    choiceChips = _choiceChips.all;
  }

  // 监听依赖变化(语言切换会触发此方法)
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    setState(() {
      // 重新获取带新标签的列表
      choiceChips = _choiceChips.all;
      // 恢复之前的选中状态
      final selectedValue = choice;
      if (selectedValue != null) {
        choiceChips = choiceChips.map((chip) {
          return chip.copy(isSelected: chip.value == selectedValue);
        }).toList();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    // 原有的build代码,ChoiceChip展示部分不变
    return ...;
  }
}

3. 优化ChoiceChipData类型安全(可选)

将var label改为final String label,明确类型避免潜在问题:

class ChoiceChipData {
  final String label;
  final String value;
  bool isSelected; // 需要修改选中状态,不能用final
  Color textColor;
  Color selectedColor;

  ChoiceChipData({
    required this.label,
    required this.value,
    required this.isSelected,
    required this.textColor,
    required this.selectedColor,
  });

  // copy方法保持不变
  ChoiceChipData copy({
    String? label,
    String? value,
    bool? isSelected,
    Color? textColor,
    Color? selectedColor,
  }) =>
      ChoiceChipData(
        label: label ?? this.label,
        value: value ?? this.value,
        isSelected: isSelected ?? this.isSelected,
        textColor: textColor ?? this.textColor,
        selectedColor: selectedColor ?? this.selectedColor,
      );

  // ==和hashCode方法保持不变
}

4. 手动语言切换时触发更新

如果是自定义语言切换逻辑,在切换语言后调用setState即可触发列表更新:

// 示例:自定义切换语言方法
void switchLanguage() {
  // 执行语言切换逻辑
  ...
  // 更新列表并恢复选中状态
  setState(() {
    choiceChips = _choiceChips.all;
    final selectedValue = choice;
    if (selectedValue != null) {
      choiceChips = choiceChips.map((chip) {
        return chip.copy(isSelected: chip.value == selectedValue);
      }).toList();
    }
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 03:01:24