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