mark
mark

Reputation: 1295

Only one checkbox to be checked at time in Flutter

I have a 3 check box in my app, which are formed by looping over the tickbox map, in my Application it allows to select multiple checkboxes but I dont want that to happen , only one should be selected at a time, is there any way to do so in flutter.

below is my code.

class _DashboardFilterState extends State<DashboardFilter> {

 void showModalSheet() {
 List<Map<String, Object>> tickbox;
 timeData = [
      {"id": "1", "displayId": "Daily"},
      {"id": "2", "displayId": "Weekly"},
      {"id": "3", "displayId": "Monthly"}
    ]; 

   showModalBottomSheet<void>(
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(10.0),
        ),
        context: context,
        builder: (BuildContext context) {
          return StatefulBuilder(
              builder: (BuildContext context, StateSetter state) {
            return createBox(context, timeData, state);
          });
        });
 }

createBox(BuildContext context,List<Map<String, Object>> tickbox, StateSetter state) {
          var tickboxdata = tickbox.map<Widget>((data) {
          int id = data["id"];
          var dispId = data["displayId"];
          return buildTimeData(context, id, dispId, state);

        }).toList();

      return SingleChildScrollView(
          child: LimitedBox(
            child: Column(
              mainAxisSize: MainAxisSize.max,
              mainAxisAlignment: MainAxisAlignment.center,
              // children: metrics,
              children: <Widget>[
              Container(
                  child: Column(
                    children: tickboxdata,
                  ),
                ),
               ],
            )),
          );
    }


     Widget buildTimeData(
          BuildContext context, var id, var disp, StateSetter state) {
        return Container(
            child: Column(mainAxisSize: MainAxisSize.min, 
         children: <Widget>[
          CheckboxListTile(
              value: widget.timeSelected[id],
              title: Text(disp),
              controlAffinity: ListTileControlAffinity.leading,
              onChanged: (bool val) {
                manageTimeState(val, id, state);
              })
        ]));
      }

    void manageTimeState(bool val, var id, StateSetter state) {
        state(() {
          widget.timeSelected[id] = val;
        });
      }

let me know if is there any other option to do so thanks

Upvotes: 6

Views: 21529

Answers (2)

MohammedAli
MohammedAli

Reputation: 2519

without any package i make the example (null safe)

Output :-

enter image description here

Example code :-

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> {
  String selected = "";
  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: [
            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(() {
                      for (var element in checkListItems) {
                        element["value"] = false;
                      }
                      checkListItems[index]["value"] = value;
                      selected =
                          "${checkListItems[index]["id"]}, ${checkListItems[index]["title"]}, ${checkListItems[index]["value"]}";
                    });
                  },
                ),
              ),
            ),
            const SizedBox(height: 100.0),
            Text(
              selected,
              style: const TextStyle(
                fontSize: 22.0,
                color: Colors.black,
                fontWeight: FontWeight.bold,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Upvotes: 9

chunhunghan
chunhunghan

Reputation: 54367

please use package https://pub.dev/packages/grouped_buttons
In onSelected, remove first selected item if more than one selected

code snippet

List<String> _checked = [];
... 
CheckboxGroup(
        labels: <String>[
          "Sunday",
          "Monday",
          "Tuesday",
          "Wednesday",
          "Thursday",
          "Friday",
          "Saturday",
        ],
        disabled: ["Wednesday", "Friday"],
        checked: _checked,
        onChange: (bool isChecked, String label, int index) =>
            print("isChecked: $isChecked   label: $label  index: $index"),
        onSelected: (List selected) => setState(() {
          if (selected.length > 1) {
            selected.removeAt(0);
            print('selected length  ${selected.length}');
          } else {
            print("only one");
          }
          _checked = selected;
        }),
      ),

full code

/*
Name: Akshath Jain
Date: 3/15/19
Purpose: example app for the grouped buttons package
*/

import 'package:flutter/material.dart';
import 'package:grouped_buttons/grouped_buttons.dart';

void main() => runApp(GroupedButtonExample());

class GroupedButtonExample extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Grouped Buttons Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<String> _checked = []; //["A", "B"];
  String _picked = "Two";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Grouped Buttons Example"),
      ),
      body: _body(),
    );
    //
  }

  Widget _body() {
    return ListView(children: <Widget>[
      //--------------------
      //SIMPLE USAGE EXAMPLE
      //--------------------

      //BASIC CHECKBOXGROUP
      Container(
        padding: const EdgeInsets.only(left: 14.0, top: 14.0),
        child: Text(
          "Basic CheckboxGroup",
          style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
        ),
      ),

      CheckboxGroup(
        labels: <String>[
          "Sunday",
          "Monday",
          "Tuesday",
          "Wednesday",
          "Thursday",
          "Friday",
          "Saturday",
        ],
        disabled: ["Wednesday", "Friday"],
        checked: _checked,
        onChange: (bool isChecked, String label, int index) =>
            print("isChecked: $isChecked   label: $label  index: $index"),
        onSelected: (List selected) => setState(() {
          if (selected.length > 1) {
            selected.removeAt(0);
            print('selected length  ${selected.length}');
          } else {
            print("only one");
          }
          _checked = selected;
        }),
      ),

      //BASIC RADIOBUTTONGROUP
      Container(
        padding: const EdgeInsets.only(left: 14.0, top: 14.0),
        child: Text(
          "Basic RadioButtonGroup",
          style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
        ),
      ),

      RadioButtonGroup(
        labels: [
          "Option 1",
          "Option 2",
        ],
        disabled: ["Option 1"],
        onChange: (String label, int index) =>
            print("label: $label index: $index"),
        onSelected: (String label) => print(label),
      ),

      //--------------------
      //CUSTOM USAGE EXAMPLE
      //--------------------

      ///CUSTOM CHECKBOX GROUP
      Container(
        padding: const EdgeInsets.only(left: 14.0, top: 14.0, bottom: 14.0),
        child: Text(
          "Custom CheckboxGroup",
          style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
        ),
      ),

      CheckboxGroup(
        orientation: GroupedButtonsOrientation.HORIZONTAL,
        margin: const EdgeInsets.only(left: 12.0),
        onSelected: (List selected) => setState(() {
          _checked = selected;
        }),
        labels: <String>[
          "A",
          "B",
        ],
        checked: _checked,
        itemBuilder: (Checkbox cb, Text txt, int i) {
          return Column(
            children: <Widget>[
              Icon(Icons.polymer),
              cb,
              txt,
            ],
          );
        },
      ),

      ///CUSTOM RADIOBUTTON GROUP
      Container(
        padding: const EdgeInsets.only(left: 14.0, top: 14.0, bottom: 14.0),
        child: Text(
          "Custom RadioButtonGroup",
          style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
        ),
      ),

      RadioButtonGroup(
        orientation: GroupedButtonsOrientation.HORIZONTAL,
        margin: const EdgeInsets.only(left: 12.0),
        onSelected: (String selected) => setState(() {
          _picked = selected;
        }),
        labels: <String>[
          "One",
          "Two",
        ],
        picked: _picked,
        itemBuilder: (Radio rb, Text txt, int i) {
          return Column(
            children: <Widget>[
              Icon(Icons.public),
              rb,
              txt,
            ],
          );
        },
      ),
    ]);
  }
}

working demo

enter image description here

Upvotes: 2

Related Questions