Fix bug when tapping ListTitle with CheckboxListTile tristate enable (#63925)
* fix bug when tap ListTitle when tristate enable #63846
* fix bug when tap ListTitle when tristate enable #63846
* code style
* improve the unit test case
* bow to convention
diff --git a/packages/flutter/lib/src/cupertino/theme.dart b/packages/flutter/lib/src/cupertino/theme.dart
index 164824a..f475e5c 100644
--- a/packages/flutter/lib/src/cupertino/theme.dart
+++ b/packages/flutter/lib/src/cupertino/theme.dart
@@ -98,7 +98,7 @@
@override
Widget build(BuildContext context) {
- return _InheritedCupertinoTheme(
+ return _InheritedCupertinoTheme(
theme: this,
child: IconTheme(
data: CupertinoIconThemeData(color: data.primaryColor),
diff --git a/packages/flutter/lib/src/material/checkbox_list_tile.dart b/packages/flutter/lib/src/material/checkbox_list_tile.dart
index b74f210..a62376e 100644
--- a/packages/flutter/lib/src/material/checkbox_list_tile.dart
+++ b/packages/flutter/lib/src/material/checkbox_list_tile.dart
@@ -382,6 +382,21 @@
/// If tristate is false (the default), [value] must not be null.
final bool tristate;
+ void _handleValueChange() {
+ assert(onChanged != null);
+ switch (value) {
+ case false:
+ onChanged(true);
+ break;
+ case true:
+ onChanged(tristate ? null : false);
+ break;
+ default: // case null:
+ onChanged(false);
+ break;
+ }
+ }
+
@override
Widget build(BuildContext context) {
final Widget control = Checkbox(
@@ -416,7 +431,7 @@
isThreeLine: isThreeLine,
dense: dense,
enabled: onChanged != null,
- onTap: onChanged != null ? () { onChanged(!value); } : null,
+ onTap: onChanged != null ? _handleValueChange : null,
selected: selected,
autofocus: autofocus,
contentPadding: contentPadding,
diff --git a/packages/flutter/lib/src/physics/spring_simulation.dart b/packages/flutter/lib/src/physics/spring_simulation.dart
index ff5b711..7d26609 100644
--- a/packages/flutter/lib/src/physics/spring_simulation.dart
+++ b/packages/flutter/lib/src/physics/spring_simulation.dart
@@ -277,7 +277,7 @@
final double power = math.pow(math.e, _r * time) as double;
final double cosine = math.cos(_w * time);
final double sine = math.sin(_w * time);
- return power * (_c2 * _w * cosine - _c1 * _w * sine) +
+ return power * (_c2 * _w * cosine - _c1 * _w * sine) +
_r * power * (_c2 * sine + _c1 * cosine);
}
diff --git a/packages/flutter/lib/src/widgets/single_child_scroll_view.dart b/packages/flutter/lib/src/widgets/single_child_scroll_view.dart
index 4c2cda4..17d08c3 100644
--- a/packages/flutter/lib/src/widgets/single_child_scroll_view.dart
+++ b/packages/flutter/lib/src/widgets/single_child_scroll_view.dart
@@ -573,7 +573,7 @@
bool _shouldClipAtPaintOffset(Offset paintOffset) {
assert(child != null);
- return paintOffset.dx < 0 ||
+ return paintOffset.dx < 0 ||
paintOffset.dy < 0 ||
paintOffset.dx + child.size.width > size.width ||
paintOffset.dy + child.size.height > size.height;
diff --git a/packages/flutter/test/material/checkbox_list_tile_test.dart b/packages/flutter/test/material/checkbox_list_tile_test.dart
index f5913d2..45487ee 100644
--- a/packages/flutter/test/material/checkbox_list_tile_test.dart
+++ b/packages/flutter/test/material/checkbox_list_tile_test.dart
@@ -148,7 +148,8 @@
});
testWidgets('CheckboxListTile tristate test', (WidgetTester tester) async {
- bool _value;
+ bool _value = false;
+ bool _tristate = false;
await tester.pumpWidget(
Material(
@@ -157,7 +158,7 @@
return wrap(
child: CheckboxListTile(
title: const Text('Title'),
- tristate: true,
+ tristate: _tristate,
value: _value,
onChanged: (bool value) {
setState(() {
@@ -171,12 +172,33 @@
),
);
- expect(tester.widget<Checkbox>(find.byType(Checkbox)).value, null);
+ expect(tester.widget<Checkbox>(find.byType(Checkbox)).value, false);
+
+ // Tap the checkbox when tristate is disabled.
+ await tester.tap(find.byType(Checkbox));
+ await tester.pumpAndSettle();
+ expect(_value, true);
await tester.tap(find.byType(Checkbox));
await tester.pumpAndSettle();
expect(_value, false);
+ // Tap the listTile when tristate is disabled.
+ await tester.tap(find.byType(ListTile));
+ await tester.pumpAndSettle();
+ expect(_value, true);
+
+ await tester.tap(find.byType(ListTile));
+ await tester.pumpAndSettle();
+ expect(_value, false);
+
+ // Enable tristate
+ _tristate = true;
+ await tester.pumpAndSettle();
+
+ expect(tester.widget<Checkbox>(find.byType(Checkbox)).value, false);
+
+ // Tap the checkbox when tristate is enabled.
await tester.tap(find.byType(Checkbox));
await tester.pumpAndSettle();
expect(_value, true);
@@ -184,5 +206,22 @@
await tester.tap(find.byType(Checkbox));
await tester.pumpAndSettle();
expect(_value, null);
+
+ await tester.tap(find.byType(Checkbox));
+ await tester.pumpAndSettle();
+ expect(_value, false);
+
+ // Tap the listTile when tristate is enabled.
+ await tester.tap(find.byType(ListTile));
+ await tester.pumpAndSettle();
+ expect(_value, true);
+
+ await tester.tap(find.byType(ListTile));
+ await tester.pumpAndSettle();
+ expect(_value, null);
+
+ await tester.tap(find.byType(ListTile));
+ await tester.pumpAndSettle();
+ expect(_value, false);
});
}