Fix tristate checkbox false to null transition, test ALL transitions (#26199)

diff --git a/packages/flutter/lib/src/material/checkbox.dart b/packages/flutter/lib/src/material/checkbox.dart
index 87c0196..d471735 100644
--- a/packages/flutter/lib/src/material/checkbox.dart
+++ b/packages/flutter/lib/src/material/checkbox.dart
@@ -342,7 +342,7 @@
 
         _initStrokePaint(paint);
         final double tShrink = (t - 0.5) * 2.0;
-        if (_oldValue == null)
+        if (_oldValue == null || value == null)
           _drawDash(canvas, origin, tShrink, paint);
         else
           _drawCheck(canvas, origin, tShrink, paint);
diff --git a/packages/flutter/test/material/checkbox_test.dart b/packages/flutter/test/material/checkbox_test.dart
index eba2aee..58945d1 100644
--- a/packages/flutter/test/material/checkbox_test.dart
+++ b/packages/flutter/test/material/checkbox_test.dart
@@ -9,6 +9,7 @@
 import 'package:flutter_test/flutter_test.dart';
 import 'package:flutter/material.dart';
 
+import '../rendering/mock_canvas.dart';
 import '../widgets/semantics_tester.dart';
 
 void main() {
@@ -286,4 +287,53 @@
     SystemChannels.accessibility.setMockMessageHandler(null);
     semanticsTester.dispose();
   });
+
+  testWidgets('CheckBox tristate rendering, programmatic transitions', (WidgetTester tester) async {
+    Widget buildFrame(bool checkboxValue) {
+      return Material(
+        child: StatefulBuilder(
+          builder: (BuildContext context, StateSetter setState) {
+            return Checkbox(
+              tristate: true,
+              value: checkboxValue,
+              onChanged: (bool value) { },
+            );
+          },
+        ),
+      );
+    }
+
+    RenderToggleable getCheckboxRenderer() {
+      return tester.renderObject<RenderToggleable>(find.byType(Checkbox));
+    }
+
+    await tester.pumpWidget(buildFrame(false));
+    await tester.pumpAndSettle();
+    expect(getCheckboxRenderer(), isNot(paints..path())); // checkmark is rendered as a path
+    expect(getCheckboxRenderer(), isNot(paints..line())); // null is rendered as a line (a "dash")
+    expect(getCheckboxRenderer(), paints..drrect()); // empty checkbox
+
+    await tester.pumpWidget(buildFrame(true));
+    await tester.pumpAndSettle();
+    expect(getCheckboxRenderer(), paints..path()); // checkmark is rendered as a path
+
+    await tester.pumpWidget(buildFrame(false));
+    await tester.pumpAndSettle();
+    expect(getCheckboxRenderer(), isNot(paints..path())); // checkmark is rendered as a path
+    expect(getCheckboxRenderer(), isNot(paints..line())); // null is rendered as a line (a "dash")
+    expect(getCheckboxRenderer(), paints..drrect()); // empty checkbox
+
+    await tester.pumpWidget(buildFrame(null));
+    await tester.pumpAndSettle();
+    expect(getCheckboxRenderer(), paints..line()); // null is rendered as a line (a "dash")
+
+    await tester.pumpWidget(buildFrame(true));
+    await tester.pumpAndSettle();
+    expect(getCheckboxRenderer(), paints..path()); // checkmark is rendered as a path
+
+    await tester.pumpWidget(buildFrame(null));
+    await tester.pumpAndSettle();
+    expect(getCheckboxRenderer(), paints..line()); // null is rendered as a line (a "dash")
+  });
+
 }