如何使用Getx实现复选框单选、多选及全选功能?
复选框替代实现方式
1. 使用CheckboxListTile组件
Flutter自带的CheckboxListTile已封装复选框+文本的组合布局,无需手动拼接容器与复选框,代码更简洁:
GetBuilder<ProductController>( builder: (controller) { return CheckboxListTile( activeColor: MyThemes.yellow, controlAffinity: ListTileControlAffinity.leading, // 复选框居左 title: Text(controller.items[index]["one"]), value: controller.items[index]["check"], onChanged: (value) { controller.checkBrand(index, value!); }, ); }, )
2. 自定义复选框组件
若需要高度定制复选框样式(比如不同状态的图标、背景),可自行封装组件:
// 自定义复选框组件 class CustomCheckbox extends StatelessWidget { final bool value; final ValueChanged<bool> onChanged; const CustomCheckbox({super.key, required this.value, required this.onChanged}); @override Widget build(BuildContext context) { return GestureDetector( onTap: () => onChanged(!value), child: Container( width: 24, height: 24, decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), border: Border.all(color: value ? MyThemes.yellow : Colors.grey), color: value ? MyThemes.yellow : Colors.transparent, ), child: value ? const Icon(Icons.check, color: Colors.white, size: 18) : null, ), ); } } // 在View中使用 GetBuilder<ProductController>( builder: (controller) { return Container( height: 50, child: Row( children: [ CustomCheckbox( value: controller.items[index]["check"], onChanged: (value) => controller.checkBrand(index, value), ), const SizedBox(width: 10), Text(controller.items[index]["one"]), ], ), ); }, )
3. 使用第三方分组复选框库
针对复杂分组选择场景,可借助grouped_checkboxes这类库简化状态管理,示例如下:
// 先在pubspec.yaml添加依赖:grouped_checkboxes: ^1.0.0 GroupedCheckboxes( items: controller.items.map((item) => item["one"]).toList(), initialSelected: controller.items.where((item) => item["check"]).map((item) => item["one"]).toList(), onChanged: (selected) { // 更新controller中items的选中状态 for (var i = 0; i < controller.items.length; i++) { controller.items[i]["check"] = selected.contains(controller.items[i]["one"]); } controller.update(); }, )
添加全选按钮的实现
第一步:更新Controller逻辑
在ProductController中添加全选状态变量及对应方法:
import 'package:get/get.dart'; class ProductController extends GetxController { RxList<Map<String, dynamic>> items = [ {"one": "Item1", "check": false}, {"one": "Item2", "check": false}, {"one": "Item3", "check": false} ].obs; // 全选状态标识 RxBool isAllSelected = false.obs; @override void onInit() { super.onInit(); // 监听items变化,自动同步全选状态 ever(items, (_) { isAllSelected.value = items.every((item) => item["check"] == true); }); } void checkBrand(int index, bool isCheck) { items[index]["check"] = isCheck; update(); } // 全选/取消全选切换方法 void toggleAllSelect(bool isAllCheck) { for (var item in items) { item["check"] = isAllCheck; } isAllSelected.value = isAllCheck; update(); } }
第二步:在View中添加全选控件
在列表顶部或合适位置插入全选按钮,示例用CheckboxListTile实现:
// 全选按钮 GetBuilder<ProductController>( builder: (controller) { return CheckboxListTile( activeColor: MyThemes.yellow, controlAffinity: ListTileControlAffinity.leading, title: const Text("全选"), value: controller.isAllSelected.value, onChanged: (value) { controller.toggleAllSelect(value!); }, ); }, ) // 原有列表项(建议用ListView.builder批量渲染) ListView.builder( itemCount: controller.items.length, itemBuilder: (context, index) { return GetBuilder<ProductController>( builder: (controller) { return Container( height: 50, child: Transform.scale( scale: 1.2, child: Checkbox( activeColor: MyThemes.yellow, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5) ), splashRadius: 18.8, value: controller.items[index]["check"], onChanged:((value) { controller.checkBrand(index, value!); } )), ), ); }, ); }, )
可选优化:手动同步全选状态
若不想用ever监听,也可在checkBrand方法中手动判断全选状态:
void checkBrand(int index, bool isCheck) { items[index]["check"] = isCheck; // 手动更新全选状态 isAllSelected.value = items.every((item) => item["check"] == true); update(); }
内容的提问来源于stack exchange,提问作者marwan steam
相关产品推荐
相关产品推荐

