Unverified Commit 91e7678f authored by William Oprandi's avatar William Oprandi Committed by GitHub

Allow null value for CheckboxListTile (#58154)

parent 997a6ffc
...@@ -248,11 +248,12 @@ class CheckboxListTile extends StatelessWidget { ...@@ -248,11 +248,12 @@ class CheckboxListTile extends StatelessWidget {
/// ///
/// The following arguments are required: /// The following arguments are required:
/// ///
/// * [value], which determines whether the checkbox is checked, and must not /// * [value], which determines whether the checkbox is checked. The [value]
/// be null. /// can only be null if [tristate] is true.
///
/// * [onChanged], which is called when the value of the checkbox should /// * [onChanged], which is called when the value of the checkbox should
/// change. It can be set to null to disable the checkbox. /// change. It can be set to null to disable the checkbox.
///
/// The value of [tristate] must not be null.
const CheckboxListTile({ const CheckboxListTile({
Key key, Key key,
@required this.value, @required this.value,
...@@ -268,7 +269,9 @@ class CheckboxListTile extends StatelessWidget { ...@@ -268,7 +269,9 @@ class CheckboxListTile extends StatelessWidget {
this.controlAffinity = ListTileControlAffinity.platform, this.controlAffinity = ListTileControlAffinity.platform,
this.autofocus = false, this.autofocus = false,
this.contentPadding, this.contentPadding,
}) : assert(value != null), this.tristate = false,
}) : assert(tristate != null),
assert(tristate || value != null),
assert(isThreeLine != null), assert(isThreeLine != null),
assert(!isThreeLine || subtitle != null), assert(!isThreeLine || subtitle != null),
assert(selected != null), assert(selected != null),
...@@ -277,8 +280,6 @@ class CheckboxListTile extends StatelessWidget { ...@@ -277,8 +280,6 @@ class CheckboxListTile extends StatelessWidget {
super(key: key); super(key: key);
/// Whether this checkbox is checked. /// Whether this checkbox is checked.
///
/// This property must not be null.
final bool value; final bool value;
/// Called when the value of the checkbox should change. /// Called when the value of the checkbox should change.
...@@ -365,6 +366,18 @@ class CheckboxListTile extends StatelessWidget { ...@@ -365,6 +366,18 @@ class CheckboxListTile extends StatelessWidget {
/// When the value is null, the `contentPadding` is `EdgeInsets.symmetric(horizontal: 16.0)`. /// When the value is null, the `contentPadding` is `EdgeInsets.symmetric(horizontal: 16.0)`.
final EdgeInsetsGeometry contentPadding; final EdgeInsetsGeometry contentPadding;
/// If true the checkbox's [value] can be true, false, or null.
///
/// Checkbox displays a dash when its value is null.
///
/// When a tri-state checkbox ([tristate] is true) is tapped, its [onChanged]
/// callback will be applied to true if the current value is false, to null if
/// value is true, and to false if value is null (i.e. it cycles through false
/// => true => null => false when tapped).
///
/// If tristate is false (the default), [value] must not be null.
final bool tristate;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final Widget control = Checkbox( final Widget control = Checkbox(
...@@ -374,6 +387,7 @@ class CheckboxListTile extends StatelessWidget { ...@@ -374,6 +387,7 @@ class CheckboxListTile extends StatelessWidget {
checkColor: checkColor, checkColor: checkColor,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
autofocus: autofocus, autofocus: autofocus,
tristate: tristate,
); );
Widget leading, trailing; Widget leading, trailing;
switch (controlAffinity) { switch (controlAffinity) {
......
...@@ -144,4 +144,43 @@ void main() { ...@@ -144,4 +144,43 @@ void main() {
expect(paddingRect.top, tallerWidget.top - remainingHeight / 2 - 18); expect(paddingRect.top, tallerWidget.top - remainingHeight / 2 - 18);
expect(paddingRect.bottom, tallerWidget.bottom + remainingHeight / 2 + 2); expect(paddingRect.bottom, tallerWidget.bottom + remainingHeight / 2 + 2);
}); });
testWidgets('CheckboxListTile tristate test', (WidgetTester tester) async {
bool _value;
await tester.pumpWidget(
Material(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return wrap(
child: CheckboxListTile(
title: const Text('Title'),
tristate: true,
value: _value,
onChanged: (bool value) {
setState(() {
_value = value;
});
},
),
);
},
),
),
);
expect(tester.widget<Checkbox>(find.byType(Checkbox)).value, null);
await tester.tap(find.byType(Checkbox));
await tester.pumpAndSettle();
expect(_value, false);
await tester.tap(find.byType(Checkbox));
await tester.pumpAndSettle();
expect(_value, true);
await tester.tap(find.byType(Checkbox));
await tester.pumpAndSettle();
expect(_value, null);
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment