在这里插入图片描述

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

🎯 欢迎来到 Flutter for OpenHarmony 社区!本文将深入讲解 Flutter 中 CheckBox 复选框组件的使用方法,带你从基础到精通,掌握这一重要的多选控件。


一、CheckBox 组件概述

在 Flutter for OpenHarmony 应用开发中,CheckBox(复选框)是一种用于在多个选项中选择一个或多个的控件。用户可以同时选择多个选项,常用于兴趣爱好选择、技能选择、权限设置等场景。

📋 CheckBox 组件特点

特点 说明
多选逻辑 可以同时选择多个
方形图标 使用方形勾选图标
独立行为 每个复选框独立工作
三态支持 支持选中、未选中、不确定三种状态
易于理解 符合用户习惯

💡 使用场景:CheckBox 常用于兴趣爱好、技能选择、权限设置、标签过滤等多选场景。


二、CheckBox 基础用法

2.1 最简单的 CheckBox

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

  
  State<CheckBoxExample> createState() => _CheckBoxExampleState();
}

class _CheckBoxExampleState extends State<CheckBoxExample> {
  bool _isChecked = false;

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('CheckBox 示例')),
      body: Center(
        child: Checkbox(
          value: _isChecked,
          onChanged: (bool? value) {
            setState(() {
              _isChecked = value!;
            });
          },
        ),
      ),
    );
  }
}

代码解析

  • value:当前复选框的选中状态
  • onChanged:选中状态改变时的回调
  • valuetrue 时显示勾选状态,false 时显示未选中状态

深入理解:与 RadioButton 不同,CheckBox 每个都是独立的,不需要 groupValue 来控制互斥。每个复选框都有自己的状态变量。

2.2 使用 CheckboxListTile

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

  
  State<CheckboxListTileExample> createState() => _CheckboxListTileExampleState();
}

class _CheckboxListTileExampleState extends State<CheckboxListTileExample> {
  bool _flutter = false;
  bool _dart = false;
  bool _react = false;

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('CheckboxListTile 示例')),
      body: ListView(
        children: [
          CheckboxListTile(
            title: const Text('Flutter'),
            subtitle: const Text('跨平台移动开发框架'),
            value: _flutter,
            onChanged: (value) {
              setState(() {
                _flutter = value!;
              });
            },
          ),
          CheckboxListTile(
            title: const Text('Dart'),
            subtitle: const Text('Flutter 开发语言'),
            value: _dart,
            onChanged: (value) {
              setState(() {
                _dart = value!;
              });
            },
          ),
          CheckboxListTile(
            title: const Text('React Native'),
            subtitle: const Text('JavaScript 跨平台框架'),
            value: _react,
            onChanged: (value) {
              setState(() {
                _react = value!;
              });
            },
          ),
        ],
      ),
    );
  }
}

⚠️ 注意事项:使用 CheckboxListTile 可以更方便地创建带有标题和副标题的复选框列表。


三、CheckBox 常用属性

3.1 value - 选中状态

控制复选框的选中状态。

Checkbox(
  value: true,
  onChanged: (value) {},
)

三态支持value 可以是 true(选中)、false(未选中)或 null(不确定状态)。

3.2 onChanged - 状态改变回调

当用户点击复选框时触发。

Checkbox(
  value: _isChecked,
  onChanged: (bool? value) {
    setState(() {
      _isChecked = value!;
    });
  },
)

注意:设为 null 时复选框禁用。

3.3 activeColor - 选中颜色

设置复选框选中时的颜色。

Checkbox(
  value: _isChecked,
  activeColor: Colors.green,
  onChanged: (value) {},
)

3.4 checkColor - 勾选图标颜色

设置复选框内部勾选图标(√)的颜色。

Checkbox(
  value: _isChecked,
  activeColor: Colors.blue,
  checkColor: Colors.white,
  onChanged: (value) {},
)

3.5 fillColor - 填充颜色

使用 MaterialStateProperty 设置不同状态下的颜色。

Checkbox(
  value: _isChecked,
  fillColor: MaterialStateProperty.resolveWith((states) {
    if (states.contains(MaterialState.selected)) {
      return Colors.blue;
    }
    return Colors.grey[300];
  }),
  onChanged: (value) {},
)

3.6 tristate - 三态模式

是否支持不确定状态(null)。

Checkbox(
  value: _tristateValue,
  tristate: true,
  onChanged: (value) {
    setState(() {
      _tristateValue = value!;
    });
  },
)

应用场景:当有子选项时,父选项可能处于"部分选中"状态。

📊 Checkbox 属性速查表

属性 类型 默认值 说明
value bool? - 选中状态(必填)
onChanged ValueChanged<bool?>? - 状态改变回调
activeColor Color? - 选中颜色
checkColor Color? - 勾选图标颜色
fillColor MaterialStateProperty<Color?>? - 填充颜色
tristate bool false 是否支持三态

四、CheckboxListTile 常用属性

4.1 title - 标题

CheckboxListTile(
  title: const Text('选项标题'),
  value: _isChecked,
  onChanged: (value) {},
)

4.2 subtitle - 副标题

CheckboxListTile(
  title: const Text('选项标题'),
  subtitle: const Text('这是选项的描述信息'),
  value: _isChecked,
  onChanged: (value) {},
)

4.3 secondary - 次要组件

CheckboxListTile(
  title: const Text('Flutter'),
  secondary: const Icon(Icons.code),
  value: _isChecked,
  onChanged: (value) {},
)

4.4 controlAffinity - 控件位置

CheckboxListTile(
  title: const Text('选项'),
  controlAffinity: ListTileControlAffinity.leading,
  value: _isChecked,
  onChanged: (value) {},
)

五、CheckBox 样式定制

5.1 自定义颜色

Checkbox(
  value: _isChecked,
  activeColor: Colors.purple,
  checkColor: Colors.white,
  onChanged: (value) {},
)

5.2 使用主题

Theme(
  data: ThemeData(
    checkboxTheme: CheckboxThemeData(
      fillColor: MaterialStateProperty.resolveWith((states) {
        if (states.contains(MaterialState.selected)) {
          return Colors.purple;
        }
        return Colors.grey[300];
      }),
      checkColor: MaterialStateProperty.all(Colors.white),
    ),
  ),
  child: Checkbox(
    value: _isChecked,
    onChanged: (value) {},
  ),
)

5.3 自定义大小

Transform.scale(
  scale: 1.5,
  child: Checkbox(
    value: _isChecked,
    onChanged: (value) {},
  ),
)

六、CheckBox 实际应用场景

6.1 兴趣爱好选择

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

  
  State<HobbySelector> createState() => _HobbySelectorState();
}

class _HobbySelectorState extends State<HobbySelector> {
  final Map<String, bool> _hobbies = {
    '编程': false,
    '阅读': false,
    '运动': false,
    '音乐': false,
    '旅行': false,
    '摄影': false,
  };

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        const Text(
          '选择兴趣爱好',
          style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
        ),
        const SizedBox(height: 16),
        ..._hobbies.entries.map((entry) {
          return CheckboxListTile(
            title: Text(entry.key),
            value: entry.value,
            onChanged: (value) {
              setState(() {
                _hobbies[entry.key] = value!;
              });
            },
          );
        }).toList(),
      ],
    );
  }
}

6.2 技能选择

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

  
  State<SkillSelector> createState() => _SkillSelectorState();
}

class _SkillSelectorState extends State<SkillSelector> {
  final List<String> _selectedSkills = [];
  final List<String> _allSkills = [
    'Flutter',
    'Dart',
    'React Native',
    'JavaScript',
    'TypeScript',
    'Python',
    'Java',
    'Kotlin',
  ];

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        Wrap(
          spacing: 8,
          runSpacing: 8,
          children: _allSkills.map((skill) {
            final isSelected = _selectedSkills.contains(skill);
            return FilterChip(
              label: Text(skill),
              selected: isSelected,
              onSelected: (selected) {
                setState(() {
                  if (selected) {
                    _selectedSkills.add(skill);
                  } else {
                    _selectedSkills.remove(skill);
                  }
                });
              },
            );
          }).toList(),
        ),
        const SizedBox(height: 16),
        Text(
          '已选择: ${_selectedSkills.join(', ')}',
          style: const TextStyle(color: Colors.grey),
        ),
      ],
    );
  }
}

设计技巧:使用 FilterChip 可以创建更现代化的多选界面。

6.3 权限设置(三态)

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

  
  State<PermissionSelector> createState() => _PermissionSelectorState();
}

class _PermissionSelectorState extends State<PermissionSelector> {
  bool? _allPermissions = false;
  bool _camera = false;
  bool _microphone = false;
  bool _location = false;

  void _updateAllPermissions() {
    final allSelected = _camera && _microphone && _location;
    final noneSelected = !_camera && !_microphone && !_location;
    setState(() {
      _allPermissions = allSelected ? true : (noneSelected ? false : null);
    });
  }

  void _toggleAll(bool? value) {
    setState(() {
      _allPermissions = value;
      _camera = value ?? false;
      _microphone = value ?? false;
      _location = value ?? false;
    });
  }

  void _togglePermission(String permission, bool value) {
    setState(() {
      switch (permission) {
        case 'camera':
          _camera = value;
          break;
        case 'microphone':
          _microphone = value;
          break;
        case 'location':
          _location = value;
          break;
      }
      _updateAllPermissions();
    });
  }

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        CheckboxListTile(
          title: const Text('全部权限'),
          tristate: true,
          value: _allPermissions,
          onChanged: _toggleAll,
        ),
        const Divider(),
        CheckboxListTile(
          title: const Text('相机'),
          subtitle: const Text('允许访问相机'),
          value: _camera,
          onChanged: (value) => _togglePermission('camera', value!),
        ),
        CheckboxListTile(
          title: const Text('麦克风'),
          subtitle: const Text('允许访问麦克风'),
          value: _microphone,
          onChanged: (value) => _togglePermission('microphone', value!),
        ),
        CheckboxListTile(
          title: const Text('位置'),
          subtitle: const Text('允许访问位置信息'),
          value: _location,
          onChanged: (value) => _togglePermission('location', value!),
        ),
      ],
    );
  }
}

应用场景:当有多个子选项时,父选项可以使用三态来显示"全部选中"、"全部未选中"或"部分选中"状态。


七、完整示例代码

import 'package:flutter/material.dart';

void main() {
  runApp(const CheckBoxDemo());
}

class CheckBoxDemo extends StatelessWidget {
  const CheckBoxDemo({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'CheckBox 组件演示',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.light(
          primary: const Color(0xFF6366F1),
          secondary: const Color(0xFF8B5CF6),
          surface: const Color(0xFFE8EAF6),
          background: const Color(0xFFF8F9FF),
          brightness: Brightness.light,
        ),
        useMaterial3: true,
      ),
      home: const CheckBoxPage(),
    );
  }
}

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

  
  State<CheckBoxPage> createState() => _CheckBoxPageState();
}

class _CheckBoxPageState extends State<CheckBoxPage> {
  final List<Map<String, dynamic>> _items = [
    {
      'title': 'Flutter',
      'subtitle': '跨平台移动开发框架',
      'icon': Icons.code,
      'color': Colors.blue,
      'checked': false,
    },
    {
      'title': 'Dart',
      'subtitle': 'Flutter 开发语言',
      'icon': Icons.terminal,
      'color': Colors.green,
      'checked': false,
    },
    {
      'title': 'React Native',
      'subtitle': 'JavaScript 跨平台框架',
      'icon': Icons.web,
      'color': Colors.orange,
      'checked': false,
    },
    {
      'title': 'TypeScript',
      'subtitle': 'JavaScript 的超集',
      'icon': Icons.data_object,
      'color': Colors.purple,
      'checked': false,
    },
  ];

  int get _checkedCount => _items.where((item) => item['checked']).length;

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        decoration: const BoxDecoration(
          gradient: LinearGradient(
            begin: Alignment.topCenter,
            end: Alignment.bottomCenter,
            colors: [
              Color(0xFFE8F4FF),
              Color(0xFFF8F9FF),
              Color(0xFFE8F4FF),
            ],
          ),
        ),
        child: SafeArea(
          child: Column(
            children: [
              // 标题区域
              Container(
                padding: const EdgeInsets.all(24),
                decoration: BoxDecoration(
                  gradient: const LinearGradient(
                    begin: Alignment.topLeft,
                    end: Alignment.bottomRight,
                    colors: [
                      Color(0xFF6366F1),
                      Color(0xFF8B5CF6),
                      Color(0xFFEC4899),
                    ],
                  ),
                  borderRadius: const BorderRadius.only(
                    bottomLeft: Radius.circular(24),
                    bottomRight: Radius.circular(24),
                  ),
                  boxShadow: [
                    BoxShadow(
                      color: const Color(0xFF6366F1).withOpacity(0.3),
                      blurRadius: 20,
                      offset: const Offset(0, 8),
                    ),
                  ],
                ),
                child: const Column(
                  children: [
                    Text(
                      '☑️ CheckBox',
                      style: TextStyle(
                        fontSize: 32,
                        fontWeight: FontWeight.bold,
                        color: Colors.white,
                      ),
                    ),
                    SizedBox(height: 8),
                    Text(
                      '探索 Flutter for OpenHarmony 中复选框组件的各种用法',
                      style: TextStyle(
                        fontSize: 16,
                        color: Colors.white,
                      ),
                    ),
                  ],
                ),
              ),

              const SizedBox(height: 24),

              // 全选按钮
              Container(
                margin: const EdgeInsets.symmetric(horizontal: 20),
                padding: const EdgeInsets.all(16),
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(16),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black.withOpacity(0.05),
                      blurRadius: 20,
                      offset: const Offset(0, 4),
                    ),
                  ],
                ),
                child: Row(
                  children: [
                    Transform.scale(
                      scale: 1.2,
                      child: Checkbox(
                        value: _checkedCount == _items.length,
                        tristate: true,
                        onChanged: (value) {
                          setState(() {
                            final allChecked = value ?? false;
                            for (var item in _items) {
                              item['checked'] = allChecked;
                            }
                          });
                        },
                        activeColor: const Color(0xFF6366F1),
                      ),
                    ),
                    const SizedBox(width: 16),
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          const Text(
                            '全选',
                            style: TextStyle(
                              fontSize: 16,
                              fontWeight: FontWeight.w600,
                              color: Color(0xFF1E293B),
                            ),
                          ),
                          Text(
                            '已选择 $_checkedCount / ${_items.length}',
                            style: const TextStyle(
                              fontSize: 13,
                              color: Color(0xFF64748B),
                            ),
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),

              const SizedBox(height: 24),

              // 选项列表
              Expanded(
                child: ListView.builder(
                  padding: const EdgeInsets.symmetric(horizontal: 20),
                  itemCount: _items.length,
                  itemBuilder: (context, index) {
                    final item = _items[index];
                    final isChecked = item['checked'];

                    return Container(
                      margin: const EdgeInsets.only(bottom: 16),
                      decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: BorderRadius.circular(16),
                        border: Border.all(
                          color: isChecked
                              ? item['color']
                              : Colors.transparent,
                          width: 2,
                        ),
                        boxShadow: [
                          BoxShadow(
                            color: Colors.black.withOpacity(0.05),
                            blurRadius: 20,
                            offset: const Offset(0, 4),
                          ),
                        ],
                      ),
                      child: CheckboxListTile(
                        value: isChecked,
                        onChanged: (value) {
                          setState(() {
                            item['checked'] = value!;
                          });
                        },
                        title: Text(
                          item['title'],
                          style: TextStyle(
                            fontSize: 16,
                            fontWeight: FontWeight.w600,
                            color: isChecked
                                ? item['color']
                                : const Color(0xFF1E293B),
                          ),
                        ),
                        subtitle: Text(
                          item['subtitle'],
                          style: const TextStyle(
                            fontSize: 13,
                            color: Color(0xFF64748B),
                          ),
                        ),
                        secondary: Container(
                          padding: const EdgeInsets.all(10),
                          decoration: BoxDecoration(
                            color: item['color'].withOpacity(0.1),
                            borderRadius: BorderRadius.circular(10),
                          ),
                          child: Icon(
                            item['icon'],
                            color: item['color'],
                            size: 24,
                          ),
                        ),
                        activeColor: item['color'],
                        contentPadding: const EdgeInsets.symmetric(
                          horizontal: 16,
                          vertical: 8,
                        ),
                      ),
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

八、总结

CheckBox 是 Flutter for OpenHarmony 中实现多选功能的重要组件,通过合理使用可以创建灵活的选择界面。

🎯 核心要点

  • 基础用法:设置 value 和 onChanged
  • 独立状态:每个复选框都是独立的
  • 三态支持:tristate 支持不确定状态
  • 样式定制:通过 activeColor、checkColor 等自定义外观
  • CheckboxListTile:更便捷的组合组件

📚 使用建议

场景 推荐方案
简单多选 使用 CheckboxListTile
兴趣爱好 使用 Map 管理状态
技能选择 使用 FilterChip
权限设置 使用三态 Checkbox
全选功能 单独实现全选逻辑

掌握 CheckBox 组件后,你可以轻松创建专业的多选界面,为用户提供灵活多样的选择体验。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐