Как сделать так, чтобы кнопка устанавливала все флажки Flutter?

#flutter #flutter-layout

#flutter #flutter-layout

Вопрос:

Проблема в том, что я не могу заставить кнопку выбрать все флажки, поскольку я использую автоматически сгенерированный список флажков.

Поскольку я создал класс с элементом списка, 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),
        ),
      ),
    ));
  }

}
 

Как можно реализовать эту функцию?

Комментарии:

1. Вы обмениваетесь данными между StatefulWidget. Вы хотели бы использовать какой-нибудь пакет, например, provider или даже riverpod ?

2. Традиционное решение похоже на получение другого текущего состояния StatefulWidget с помощью GlobalKey. А затем управлять ими. Или что-то в этом роде inheritedwidget . Гораздо проще выполнить ваше дело с помощью некоторых пакетов.

Ответ №1:

Если вы введете bool checked = false; как

 class WordBlock extends StatefulWidget {

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

Вы можете изменить его и получить доступ к нему из _WordBlockState в качестве виджета.проверено

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

 

он может быть изменен как классом, так и не константой.

Комментарии:

1. Привет! Спасибо за ответ! К сожалению, в этом случае метод OnChanged () не работает, все значения меняются и т.д., однако метод OnChanged не работает.((

Ответ №2:

попробуйте приведенный ниже код для проверки и снятия флажков с кнопки all

Вывод :-

введите описание изображения здесь

Код :-

 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,
              ),
            ),
          ],
        ),
      ),
    );
  }
}