在这里插入图片描述

案例概述

本案例展示如何使用 CheckboxListTile 创建复选框列表,允许用户选择多个选项。

核心概念

1. Checkbox

  • 基础复选框组件;
  • 支持选中/未选中/不确定三种状态;
  • 通常与 StatefulWidget 结合使用。

2. CheckboxListTile

  • 包含标题和描述的复选框;
  • 整个区域都可点击;
  • 适合列表中使用。

3. 多选管理

  • 使用 Map<String, bool> 管理多个选项的状态;
  • 或使用 List<String> 存储选中的项。

代码详解

1. 复选框列表

final Map<String, bool> _interests = {
  '编程': false,
  '设计': false,
  '产品': false,
};

..._interests.entries.map((entry) {
  return CheckboxListTile(
    title: Text(entry.key),
    value: entry.value,
    onChanged: (bool? value) {
      setState(() {
        _interests[entry.key] = value ?? false;
      });
    },
  );
}).toList()

2. 获取选中项

List<String> getSelectedItems() {
  return _interests.entries
      .where((e) => e.value)
      .map((e) => e.key)
      .toList();
}

3. 全选/取消全选

void selectAll() {
  setState(() {
    _interests.updateAll((key, value) => true);
  });
}

void deselectAll() {
  setState(() {
    _interests.updateAll((key, value) => false);
  });
}

高级话题:复选框的高级应用

1. 复选框验证

validator: (value) {
  if (getSelectedItems().isEmpty) {
    return '至少选择一个选项';
  }
  return null;
}

2. 条件复选框

某些复选框的启用/禁用取决于其他选项:

CheckboxListTile(
  title: Text('高级选项'),
  enabled: _interests['基础选项'] ?? false,
  value: _interests['高级选项'],
  onChanged: _interests['基础选项'] ?? false
      ? (bool? value) {
          setState(() {
            _interests['高级选项'] = value ?? false;
          });
        }
      : null,
)

3. 复选框分组

ExpansionTile(
  title: Text('兴趣爱好'),
  children: [
    CheckboxListTile(title: Text('编程'), value: ..., onChanged: ...),
    CheckboxListTile(title: Text('设计'), value: ..., onChanged: ...),
  ],
)

4. 复选框的计数显示

Text(
  '已选择:${_interests.entries.where((e) => e.value).length} 项',
  style: TextStyle(fontWeight: FontWeight.bold),
)

5. 复选框的样式自定义

CheckboxListTile(
  title: Text('选项'),
  activeColor: Colors.green,
  checkColor: Colors.white,
  value: true,
  onChanged: (value) {},
)

6. 复选框的响应式布局

在不同屏幕宽度上调整布局:

final isWideScreen = MediaQuery.of(context).size.width > 600;

if (isWideScreen) {
  // 显示为网格
  GridView.count(
    crossAxisCount: 2,
    children: _interests.entries.map((entry) {
      return CheckboxListTile(title: Text(entry.key), ...);
    }).toList(),
  );
} else {
  // 显示为列表
  Column(
    children: _interests.entries.map((entry) {
      return CheckboxListTile(title: Text(entry.key), ...);
    }).toList(),
  );
}

7. 复选框的动画效果

AnimatedCheckbox(
  value: _isSelected,
  onChanged: (value) {
    setState(() {
      _isSelected = value;
    });
  },
)

8. 复选框的键盘导航

Focus(
  onKey: (node, event) {
    if (event.isKeyPressed(LogicalKeyboardKey.space)) {
      setState(() {
        _isSelected = !_isSelected;
      });
      return KeyEventResult.handled;
    }
    return KeyEventResult.ignored;
  },
  child: Checkbox(value: _isSelected, onChanged: ...),
)

9. 复选框的无障碍支持

CheckboxListTile(
  title: Text('选项'),
  semanticLabel: '选择此选项',
  value: true,
  onChanged: (value) {},
)

10. 复选框状态的持久化

Future<void> _saveSavedItems() async {
  final prefs = await SharedPreferences.getInstance();
  final selected = getSelectedItems();
  await prefs.setStringList('selected_items', selected);
}

Future<void> _loadSavedItems() async {
  final prefs = await SharedPreferences.getInstance();
  final selected = prefs.getStringList('selected_items') ?? [];
  setState(() {
    _interests.updateAll((key, value) => selected.contains(key));
  });
}

通过这些高级技巧,你可以构建出功能完整的多选系统。

高级话题:复选框的企业级应用

1. 全选/取消全选

void selectAll() {
  setState(() {
    _interests.updateAll((key, value) => true);
  });
}

void deselectAll() {
  setState(() {
    _interests.updateAll((key, value) => false);
  });
}

2. 条件复选框

CheckboxListTile(
  title: Text('高级选项'),
  enabled: _interests['基础选项'] ?? false,
  value: _interests['高级选项'],
  onChanged: _interests['基础选项'] ?? false ? (bool? value) { ... } : null,
)

3. 复选框分组

ExpansionTile(
  title: Text('兴趣爱好'),
  children: [
    CheckboxListTile(title: Text('编程'), value: ..., onChanged: ...),
    CheckboxListTile(title: Text('设计'), value: ..., onChanged: ...),
  ],
)

4. 复选框的计数

Text('已选择:${_interests.entries.where((e) => e.value).length} 项')

5. 复选框的响应式布局

final isWideScreen = MediaQuery.of(context).size.width > 600;
if (isWideScreen) {
  // 显示为网格
  GridView.count(crossAxisCount: 2, children: ...)
} else {
  // 显示为列表
  Column(children: ...)
}

6. 复选框的状态持久化

Future<void> _saveSavedItems() async {
  final prefs = await SharedPreferences.getInstance();
  final selected = getSelectedItems();
  await prefs.setStringList('selected_items', selected);
}

7. 复选框的键盘导航

Focus(
  onKey: (node, event) {
    if (event.isKeyPressed(LogicalKeyboardKey.space)) {
      setState(() => _isSelected = !_isSelected);
      return KeyEventResult.handled;
    }
    return KeyEventResult.ignored;
  },
  child: Checkbox(...),
)

8. 复选框的动画效果

AnimatedCheckbox(
  value: _isSelected,
  onChanged: (value) => setState(() => _isSelected = value),
)

9. 复选框的无障碍支持

CheckboxListTile(
  title: Text('选项'),
  semanticLabel: '选择此选项',
  value: true,
  onChanged: (value) {},
)

10. 复选框的验证

validator: (value) {
  if (getSelectedItems().isEmpty) {
    return '至少选择一个选项';
  }
  return null;
}

通过这些企业级技巧,你可以构建出功能完整的多选系统。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐