'How do you add a label (title text) to a Checkbox in Flutter?

I am playing with Checkbox to see how it works, but I don't see a title option with it.

Checkbox(
  title: Text("Checkbox label"),  // The named parameter 'title' isn't defined.
  value: true,
  onChanged: (newValue) { },
);

Do I have to create my own widget to add a title to it?



Solution 1:[1]

If you need a Checkbox with a label then you can use a CheckboxListTile.

enter image description here

  CheckboxListTile(
    title: Text("title text"), //    <-- label
    value: checkedValue,
    onChanged: (newValue) { ... },
  )

If you want the checkbox on the left of the text then you can set the controlAffinity parameter.

enter image description here

  CheckboxListTile(
    title: Text("title text"),
    value: checkedValue,
    onChanged: (newValue) { ... },
    controlAffinity: ListTileControlAffinity.leading,  //  <-- leading Checkbox
  )

Notes

  • Since it is a ListTile, clicking anywhere on the row activates the onChanged() callback. You need to rebuild it with the correct checked values yourself, though. See this answer.
  • An alternate solution would be to make your own widget using a Row with a Checkbox and a Text widget. You would probably want to wrap it in a gesture detector, though, so that taps on the text would also trigger an onChanged() callback. You could start with the CheckboxListTile source code as a reference.

Solution 2:[2]

The CheckboxListTile wasn't quite right for my use case, so I took the LabeledCheckbox class from the docs and modified it a little:

import 'package:flutter/material.dart';

class LabeledCheckbox extends StatelessWidget {
  const LabeledCheckbox({
    Key? key,
    required this.label,
    required this.value,
    required this.onChanged,
  }) : super(key: key);

  final String label;
  final bool value;
  final Function onChanged;

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: () {
        onChanged(!value);
      },
      child: Row(
        children: <Widget>[
          Checkbox(
            value: value,
            onChanged: (bool? newValue) {
              onChanged(newValue);
            },
          ),
          Text(label),
        ],
      ),
    );
  }
}

Solution 3:[3]

Here is a simple stateful version.

import 'package:flutter/material.dart';

class LabeledCheckbox extends StatefulWidget {
  final bool? value;
  final String label;
  final bool leadingCheckbox;
  final ValueChanged<bool?>? onChanged;

  const LabeledCheckbox({
    Key? key,
    this.value,
    this.onChanged,
    this.label = '',
    this.leadingCheckbox = true,
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() => _LabeledCheckboxState();
}

class _LabeledCheckboxState extends State<LabeledCheckbox> {
  var value = false;

  @override
  void initState() {
    super.initState();
    value = widget.value == true;
  }

  @override
  Widget build(BuildContext context) {
    var widgets = <Widget>[
      _buildCheckbox(context),
    ];
    if (widget.label.isNotEmpty) {
      if (widget.leadingCheckbox) {
        widgets.add(_buildLabel(context));
      } else {
        widgets.insert(0, _buildLabel(context));
      }
    }
    return InkWell(
      borderRadius: BorderRadius.circular(4),
      onTap: () => _onCheckedChanged(),
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: widgets,
      ),
    );
  }

  Widget _buildCheckbox(BuildContext context) {
    return Checkbox(
      value: value,
      onChanged: (v) => _onCheckedChanged(),
    );
  }

  Widget _buildLabel(BuildContext context) {
    var padding =
        widget.leadingCheckbox ? const EdgeInsets.only(right: 8) : const EdgeInsets.only(left: 8);

    return Padding(
      padding: padding,
      child: Text(widget.label),
    );
  }

  void _onCheckedChanged() {
    setState(() {
      value = !value;
    });
    if (widget.onChanged != null) {
      widget.onChanged!.call(value);
    }
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Suragch
Solution 2 Rafa? G.
Solution 3 david.krasznai