【问题标题】:How to make a button select all Flutter checkboxes?如何使按钮选择所有 Flutter 复选框?
【发布时间】:2020-12-25 05:39:16
【问题描述】:

问题是我无法让按钮选择所有复选框,因为我使用的是自动生成的复选框列表。

由于我创建了一个带有列表项 WordBlock 的类,它是一个带有复选框的容器,并且每个复选框都有自己的选中值,因此我无法以任何方式选择所有内容。如果我通过构造函数设置选中的值,那么它会选择所有内容,但是 onChanged() 方法不起作用并且一个复选框的值不会改变。但是您需要能够一次选择一个或一次全部选择复选框,使用按钮选择全部。

这是列表中出现的我的 WordBlock 类的代码。

class WordBlock extends StatefulWidget {

  final bool checkAll;
  WordBlock(this.checkAll);
  @override
  _WordBlockState createState() => _WordBlockState();
}

class _WordBlockState extends State<WordBlock> {
  FlutterTts tts = FlutterTts();
  bool checked = false;
  Future _speak(String text) async {
    await tts.setLanguage('en-US');
    await tts.speak(text);
  }

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.symmetric(horizontal: 35.w),
      child: Card(
        color: checked ? MyColors().scaffoldBG : Colors.white,
        elevation: 4.0,
        shadowColor: MyColors().black.withOpacity(0.1),
        shape:
            RoundedRectangleBorder(borderRadius: BorderRadius.circular(25.ssp)),
        child: CheckboxListTile(
          value: checked,
          activeColor: MyColors().purple,
          onChanged: (value) {
            print('changed');
            setState(() {
              checked = value;
            });
          },
          title: h2(text: 'Car'),
          secondary: Padding(
            padding: EdgeInsets.only(top: 10.h),
            child: InkWell(
              onTap: () => _speak('Car'),
              child: Icon(
                Icons.volume_up_rounded,
                color: MyColors().purple,
                size: 60.ssp,
              ),
            ),
          ),
          subtitle: Text(
            'Машина',
            style: TextStyle(color: Color(0xFFB8A98BA), fontSize: 27.ssp),
          ),
        ),
      ),
    );
  }
}

这是显示 WordBloc 列表的页面的代码:

class WordPage extends StatefulWidget {
  @override
  _WordPageState createState() => _WordPageState();
}

class _WordPageState extends State<WordPage> {
  bool visible = true;
  double banerHeight;
  bool checked = false;

  @override
  void initState() {
    super.initState();
  }

  Widget _wrapWithBanner() {
    if (!visible) {
      setState(() {
        banerHeight = 0;
      });
    }
    return visible
        ? Container(
            margin: EdgeInsets.only(
                left: 35.w, right: 35.w, top: 30.h, bottom: 30.h),
            padding: EdgeInsets.symmetric(vertical: 25.h),
            decoration: BoxDecoration(
                borderRadius: BorderRadius.circular(25.ssp),
                color: MyColors().scaffoldBG,
                boxShadow: [boxShadow4Y10Blur()]),
            child: ListTile(
              onTap: () {
                print('close');
              },
              trailing: visible
                  ? InkWell(
                      onTap: () {
                        print('tapped');
                        setState(() {
                          visible = false;
                        });
                      },
                      child: Icon(Icons.close))
                  : Container(),
              leading: CircleAvatar(),
              title: h3bold(text: 'Совет'),
              subtitle: Text(
                'Чтобы запомнить как можно больше слов, регулярно повторяйте их: каждые два-три часа :)',
                style: TextStyle(color: MyColors().black, fontSize: 27.ssp),
              ),
            ))
        : Container();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child: Scaffold(
      backgroundColor: MyColors().white,
      appBar: AppBar(
        elevation: 2.0,
        title: h2(text: 'Работа'),
        iconTheme: IconThemeData(size: 20.ssp, color: MyColors().purple),
        backgroundColor: MyColors().white,
      ),
      body: Column(
        children: [
          _wrapWithBanner(),
          Row(
            children: [
              FlatButton( // my selectAll button
                  onPressed: () {},
                  child: Row(
                    children: [
                      Checkbox(
                          value: checked,
                          onChanged: (val) {
                            setState(() {
                              checked = val;
                            });
                          }),
                      Text(
                        'Выделить все',
                        style: TextStyle(
                            color: MyColors().purple, fontSize: 27.ssp),
                      )
                    ],
                  ))
            ],
          ),
          Expanded(
              child: ListView.builder(
            itemCount: 4,
            itemBuilder: (context, index) {
              return WordBlock(checked);
            },
          ))
        ],
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButton: Container(
        width: 667.w,
        height: 91.h,
        child: FloatingActionButton(
          backgroundColor: MyColors().purple,
          onPressed: () {},
          shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(24.ssp)),
          child: h2reg(
              text: "Добавить в мой словарь", textColor: MyColors().white),
        ),
      ),
    ));
  }

}

这个功能如何实现?

【问题讨论】:

  • 你在 statefulWidget 之间共享数据。您想使用provider 甚至riverpod 之类的包吗?
  • 传统解决方案就像是通过 GlobalKey 获取其他 statefulWidget 当前状态。然后控制它们。或类似inheritedwidget 的东西。使用一些包帮助来处理您的案例要容易得多。

标签: flutter flutter-layout


【解决方案1】:

如果你把bool checked = false; 输入为

class WordBlock extends StatefulWidget {

 bool checked = false;
  WordBlock();
  @override
  _WordBlockState createState() => _WordBlockState();
}

您可以更改它并从 _WordBlockState 作为 widget.checked 访问它


Checkbox(
          value: widget.checked,
          onChanged: (val) {
           setState(() {
           widget.checked = val;
           });
          }),

它可以被类修改,而不是常量。

【讨论】:

  • 您好!感谢你的回答!不幸的是,在这种情况下 onChanged() 方法不起作用,所有值都发生变化等,但是 onChanged 方法不起作用。((
【解决方案2】:

尝试下面的代码,使用按钮所有复选框选中和取消选中

输出:-

代码:-

import 'package:flutter/material.dart';

class CheckBoxExample extends StatefulWidget {
  const CheckBoxExample({Key? key}) : super(key: key);

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

class _CheckBoxExampleState extends State<CheckBoxExample> {
  List multipleSelected = [];
  List checkListItems = [
    {
      "id": 0,
      "value": false,
      "title": "Sunday",
    },
    {
      "id": 1,
      "value": false,
      "title": "Monday",
    },
    {
      "id": 2,
      "value": false,
      "title": "Tuesday",
    },
    {
      "id": 3,
      "value": false,
      "title": "Wednesday",
    },
    {
      "id": 4,
      "value": false,
      "title": "Thursday",
    },
    {
      "id": 5,
      "value": false,
      "title": "Friday",
    },
    {
      "id": 6,
      "value": false,
      "title": "Saturday",
    },
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 64.0),
        child: Column(
          children: [
            InkWell(
              onTap: () => setState(() {
                multipleSelected.clear();
                for (var element in checkListItems) {
                  if (element["value"] == false) {
                    element["value"] = true;
                    multipleSelected.add(element);
                  } else {
                    element["value"] = false;
                    multipleSelected.remove(element);
                  }
                }
              }),
              child: const Text(
                "Select All",
                style: TextStyle(
                  fontSize: 22.0,
                  color: Colors.black,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
            Column(
              children: List.generate(
                checkListItems.length,
                (index) => CheckboxListTile(
                  controlAffinity: ListTileControlAffinity.leading,
                  contentPadding: EdgeInsets.zero,
                  dense: true,
                  title: Text(
                    checkListItems[index]["title"],
                    style: const TextStyle(
                      fontSize: 16.0,
                      color: Colors.black,
                    ),
                  ),
                  value: checkListItems[index]["value"],
                  onChanged: (value) {
                    setState(() {
                      checkListItems[index]["value"] = value;
                    });
                  },
                ),
              ),
            ),
            Text(
              multipleSelected.isEmpty ? "" : multipleSelected.toString(),
              style: const TextStyle(
                fontSize: 22.0,
                color: Colors.black,
                fontWeight: FontWeight.bold,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-29
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 2019-02-14
    • 2014-05-23
    • 2012-07-14
    相关资源
    最近更新 更多