Skip to content

Commit 2e10b46

Browse files
authored
Fix Local CheckBoxTheme not being inherited by CheckBox Widget (#97715)
1 parent ab89ce2 commit 2e10b46

File tree

2 files changed

+50
-13
lines changed

2 files changed

+50
-13
lines changed

packages/flutter/lib/src/material/checkbox.dart

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import 'package:flutter/widgets.dart';
66

7+
import 'checkbox_theme.dart';
78
import 'constants.dart';
89
import 'debug.dart';
910
import 'material_state.dart';
@@ -403,11 +404,12 @@ class _CheckboxState extends State<Checkbox> with TickerProviderStateMixin, Togg
403404
Widget build(BuildContext context) {
404405
assert(debugCheckHasMaterial(context));
405406
final ThemeData themeData = Theme.of(context);
407+
final CheckboxThemeData checkboxTheme = CheckboxTheme.of(context);
406408
final MaterialTapTargetSize effectiveMaterialTapTargetSize = widget.materialTapTargetSize
407-
?? themeData.checkboxTheme.materialTapTargetSize
409+
?? checkboxTheme.materialTapTargetSize
408410
?? themeData.materialTapTargetSize;
409411
final VisualDensity effectiveVisualDensity = widget.visualDensity
410-
?? themeData.checkboxTheme.visualDensity
412+
?? checkboxTheme.visualDensity
411413
?? themeData.visualDensity;
412414
Size size;
413415
switch (effectiveMaterialTapTargetSize) {
@@ -422,7 +424,7 @@ class _CheckboxState extends State<Checkbox> with TickerProviderStateMixin, Togg
422424

423425
final MaterialStateProperty<MouseCursor> effectiveMouseCursor = MaterialStateProperty.resolveWith<MouseCursor>((Set<MaterialState> states) {
424426
return MaterialStateProperty.resolveAs<MouseCursor?>(widget.mouseCursor, states)
425-
?? themeData.checkboxTheme.mouseCursor?.resolve(states)
427+
?? checkboxTheme.mouseCursor?.resolve(states)
426428
?? MaterialStateMouseCursor.clickable.resolve(states);
427429
});
428430

@@ -432,37 +434,37 @@ class _CheckboxState extends State<Checkbox> with TickerProviderStateMixin, Togg
432434
final Set<MaterialState> inactiveStates = states..remove(MaterialState.selected);
433435
final Color effectiveActiveColor = widget.fillColor?.resolve(activeStates)
434436
?? _widgetFillColor.resolve(activeStates)
435-
?? themeData.checkboxTheme.fillColor?.resolve(activeStates)
437+
?? checkboxTheme.fillColor?.resolve(activeStates)
436438
?? _defaultFillColor.resolve(activeStates);
437439
final Color effectiveInactiveColor = widget.fillColor?.resolve(inactiveStates)
438440
?? _widgetFillColor.resolve(inactiveStates)
439-
?? themeData.checkboxTheme.fillColor?.resolve(inactiveStates)
441+
?? checkboxTheme.fillColor?.resolve(inactiveStates)
440442
?? _defaultFillColor.resolve(inactiveStates);
441443

442444
final Set<MaterialState> focusedStates = states..add(MaterialState.focused);
443445
final Color effectiveFocusOverlayColor = widget.overlayColor?.resolve(focusedStates)
444446
?? widget.focusColor
445-
?? themeData.checkboxTheme.overlayColor?.resolve(focusedStates)
447+
?? checkboxTheme.overlayColor?.resolve(focusedStates)
446448
?? themeData.focusColor;
447449

448450
final Set<MaterialState> hoveredStates = states..add(MaterialState.hovered);
449451
final Color effectiveHoverOverlayColor = widget.overlayColor?.resolve(hoveredStates)
450452
?? widget.hoverColor
451-
?? themeData.checkboxTheme.overlayColor?.resolve(hoveredStates)
453+
?? checkboxTheme.overlayColor?.resolve(hoveredStates)
452454
?? themeData.hoverColor;
453455

454456
final Set<MaterialState> activePressedStates = activeStates..add(MaterialState.pressed);
455457
final Color effectiveActivePressedOverlayColor = widget.overlayColor?.resolve(activePressedStates)
456-
?? themeData.checkboxTheme.overlayColor?.resolve(activePressedStates)
458+
?? checkboxTheme.overlayColor?.resolve(activePressedStates)
457459
?? effectiveActiveColor.withAlpha(kRadialReactionAlpha);
458460

459461
final Set<MaterialState> inactivePressedStates = inactiveStates..add(MaterialState.pressed);
460462
final Color effectiveInactivePressedOverlayColor = widget.overlayColor?.resolve(inactivePressedStates)
461-
?? themeData.checkboxTheme.overlayColor?.resolve(inactivePressedStates)
463+
?? checkboxTheme.overlayColor?.resolve(inactivePressedStates)
462464
?? effectiveActiveColor.withAlpha(kRadialReactionAlpha);
463465

464466
final Color effectiveCheckColor = widget.checkColor
465-
?? themeData.checkboxTheme.checkColor?.resolve(states)
467+
?? checkboxTheme.checkColor?.resolve(states)
466468
?? const Color(0xFFFFFFFF);
467469

468470
return Semantics(
@@ -481,7 +483,7 @@ class _CheckboxState extends State<Checkbox> with TickerProviderStateMixin, Togg
481483
..reactionColor = effectiveActivePressedOverlayColor
482484
..hoverColor = effectiveHoverOverlayColor
483485
..focusColor = effectiveFocusOverlayColor
484-
..splashRadius = widget.splashRadius ?? themeData.checkboxTheme.splashRadius ?? kRadialReactionRadius
486+
..splashRadius = widget.splashRadius ?? checkboxTheme.splashRadius ?? kRadialReactionRadius
485487
..downPosition = downPosition
486488
..isFocused = states.contains(MaterialState.focused)
487489
..isHovered = states.contains(MaterialState.hovered)
@@ -490,10 +492,10 @@ class _CheckboxState extends State<Checkbox> with TickerProviderStateMixin, Togg
490492
..checkColor = effectiveCheckColor
491493
..value = value
492494
..previousValue = _previousValue
493-
..shape = widget.shape ?? themeData.checkboxTheme.shape ?? const RoundedRectangleBorder(
495+
..shape = widget.shape ?? checkboxTheme.shape ?? const RoundedRectangleBorder(
494496
borderRadius: BorderRadius.all(Radius.circular(1.0)),
495497
)
496-
..side = _resolveSide(widget.side) ?? _resolveSide(themeData.checkboxTheme.side),
498+
..side = _resolveSide(widget.side) ?? _resolveSide(checkboxTheme.side),
497499
),
498500
);
499501
}

packages/flutter/test/material/checkbox_theme_test.dart

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,41 @@ void main() {
351351
reason: 'Active pressed Checkbox should have overlay color: $activePressedOverlayColor',
352352
);
353353
});
354+
355+
testWidgets('Local CheckboxTheme can override global CheckboxTheme', (WidgetTester tester) async {
356+
const Color globalThemeFillColor = Color(0xfffffff1);
357+
const Color globalThemeCheckColor = Color(0xff000000);
358+
const Color localThemeFillColor = Color(0xffff0000);
359+
const Color localThemeCheckColor = Color(0xffffffff);
360+
361+
Widget buildCheckbox({required bool active}) {
362+
return MaterialApp(
363+
theme: ThemeData(
364+
checkboxTheme: CheckboxThemeData(
365+
checkColor: MaterialStateProperty.all<Color>(globalThemeCheckColor),
366+
fillColor: MaterialStateProperty.all<Color>(globalThemeFillColor),
367+
),
368+
),
369+
home: Scaffold(
370+
body: CheckboxTheme(
371+
data: CheckboxThemeData(
372+
fillColor: MaterialStateProperty.all<Color>(localThemeFillColor),
373+
checkColor: MaterialStateProperty.all<Color>(localThemeCheckColor),
374+
),
375+
child: Checkbox(
376+
value: active,
377+
onChanged: (_) { },
378+
),
379+
),
380+
),
381+
);
382+
}
383+
384+
await tester.pumpWidget(buildCheckbox(active: true));
385+
await tester.pumpAndSettle();
386+
expect(_getCheckboxMaterial(tester), paints..path(color: localThemeFillColor));
387+
expect(_getCheckboxMaterial(tester), paints..path(color: localThemeFillColor)..path(color: localThemeCheckColor));
388+
});
354389
}
355390

356391
Future<void> _pointGestureToCheckbox(WidgetTester tester) async {

0 commit comments

Comments
 (0)