如何根据flutter中的按钮点击来选择和取消选择所有复选框

问题描述 投票:0回答:1

我有一个列表视图,其中包含 listTile 内的复选框。这个listTile将根据列表的长度动态生成。这是我的 ListTile 和自定义复选框代码。

   ListTile(
        leading: Container(
            height: 30,
            width: 42,
            decoration: const BoxDecoration(
                image: DecorationImage(
                    image: AssetImage(
                        "assets/images/ic_subtract.png"),
                    fit: BoxFit.fill)),
            child: const Image(
            image: AssetImage(
                "assets/images/ic_dummy_project_icon.png"),
            width: 24,
            height: 24,
            )),
        title: Text(
            eventTicketList[index]
                .firstName
                .toString(),
            style: const TextStyle(
                color: Color.fromRGBO(
                    26, 49, 60, 1),
                fontWeight: FontWeight.w500,
                fontSize: 16,
                fontFamily: 'SF Pro Text')),
        subtitle: loadTicketInfo(
            eventTicketList, index),
        trailing: loadCheckBox(isChecked))
 loadCheckBox(bool isChecked) {
    return CustomCheckbox(
      value: isChecked,
      onChanged: (value) {
        setState(() {
          isChecked = value!;
        })
      },
    );
class CustomCheckbox extends StatefulWidget {
  const CustomCheckbox({
    required this.value,
    Key? key,
    this.width = 24.0,
    this.height = 24.0,
    this.color,
    this.iconSize,
    this.onChanged,
    this.checkColor,
  }) : super(key: key);

  final double width;
  final double height;
  final Color? color;
  final bool? value;
  // Now you can set the checkmark size of your own
  final double? iconSize;
  final Color? checkColor;
  final Function(bool?)? onChanged;

  @override
  State<CustomCheckbox> createState() => _CustomCheckboxState();
}

class _CustomCheckboxState extends State<CustomCheckbox> {
  bool isChecked = false;

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
        setState(() => isChecked = !isChecked);
        widget.onChanged?.call(isChecked);
      },
      child: Container(
          width: widget.width,
          height: widget.height,
          child: isChecked
              ? Image(
            image: AssetImage("assets/images/ic_checked.png"),
            height: 24,
            width: 24,
            alignment: Alignment.topRight,
          )
              : Image(
            image: AssetImage("assets/images/ic_selector.png"),
            height: 24,
            width: 24,
            alignment: Alignment.topRight,
          )
      ),
    );
  }
}

我想在单击按钮时选择所有复选框,并且在再次单击同一按钮时取消选择所有复选框。我尝试了来自 stackoverflow 和其他不同来源的一些示例。但没有任何效果,或者我没有正确地做到这一点。有人可以帮我解决这个问题吗?

 Padding(
    padding: EdgeInsets.only(right: 25),
    child: TextButton(
        child: const Text("Select All",
            style: TextStyle(
                fontSize: 16,
                fontFamily: 'SF Pro Text',
                fontWeight: FontWeight.w200,
                color: Color.fromRGBO(
                    0, 94, 180, 1))),
        onPressed: () {
          //select all checkbox
        }))
flutter listview checkbox
1个回答
0
投票

您需要做的就是覆盖 CustomCheckbox 小部件内的 didUpdateWidget。因为 CustomCheckBox 小部件是有状态小部件,所以您不会多次调用它的 initState 来设置

isChecked
DidUpdateWidget
被调用,然后是
build
方法。

@override
  void didUpdateWidget(covariant CustomCheckbox oldWidget) {
    super.didUpdateWidget(oldWidget);

    if (widget.value != oldWidget.value) {
      isChecked = widget.value!;
    }
  }

这是我尝试过的完整代码

import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
      home: const HomePage(),
    );
  }
}

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

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  bool _isAllChecked = false;

  final List<String> _items = const [
    'London',
    'Paris',
    'New York',
    'Berlin',
    'Madrid'
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Checkboxes'),
        actions: [
          Checkbox.adaptive(
              value: _isAllChecked,
              onChanged: (value) {
                if (value == null) {
                  return;
                }
                setState(() {
                  _isAllChecked = value;
                });
              }),
        ],
      ),
      body: ListView.builder(
        itemBuilder: (context, index) {
          return ListTile(
              title: Text(
                _items[index],
              ),
              trailing: loadCheckBox(_isAllChecked));
        },
        itemCount: _items.length,
      ),
    );
  }

  loadCheckBox(bool isChecked) {
    return CustomCheckbox(
      value: isChecked,
      onChanged: (value) {
        setState(() {
          isChecked = value!;
        });
      },
    );
  }
}

class CustomCheckbox extends StatefulWidget {
  const CustomCheckbox({
    required this.value,
    super.key,
    this.width = 24.0,
    this.height = 24.0,
    this.color,
    this.iconSize,
    this.onChanged,
    this.checkColor,
  });

  final double width;
  final double height;
  final Color? color;
  final bool? value;
  // Now you can set the checkmark size of your own
  final double? iconSize;
  final Color? checkColor;
  final Function(bool?)? onChanged;

  @override
  State<CustomCheckbox> createState() => _CustomCheckboxState();
}

class _CustomCheckboxState extends State<CustomCheckbox> {
  bool isChecked = false;

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
        setState(() => isChecked = !isChecked);
        widget.onChanged?.call(isChecked);
      },
      child: SizedBox(
        width: widget.width,
        height: widget.height,
        child: isChecked
            ? const Icon(Icons.check_box)
            : const Icon(Icons.check_box_outline_blank),
      ),
    );
  }

  @override
  void didUpdateWidget(covariant CustomCheckbox oldWidget) {
    super.didUpdateWidget(oldWidget);

    if (widget.value != oldWidget.value) {
      isChecked = widget.value!;
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.