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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 08:55:21