From c386acca5455317894a883f5f1adcdfa78631b2e Mon Sep 17 00:00:00 2001 From: Taha Tesser Date: Sat, 11 May 2024 02:37:05 +0300 Subject: [PATCH] Fix `MaterialStateBorderSide` lerp in the `Checkbox` and chips (#148124) fixes [`Checkbox` and Chips side with `MaterialStateBorderSide` doesn't lerp in their theme](https://github.com/flutter/flutter/issues/135136) ### Code sample
expand to view the code sample ```dart import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { testWidgets('test', (WidgetTester tester) async { late ColorScheme colorScheme; Widget buildCheckbox({required Color seedColor}) { colorScheme = ColorScheme.fromSeed(seedColor: seedColor); return MaterialApp( theme: ThemeData( colorScheme: colorScheme, checkboxTheme: CheckboxThemeData( side: MaterialStateBorderSide.resolveWith( (Set states) { return BorderSide( color: colorScheme.primary, width: 4.0, ); }), ), ), home: Scaffold( body: Center( child: Checkbox( value: false, onChanged: (_) {}, ), ), ), ); } await tester.pumpWidget(buildCheckbox(seedColor: Colors.red)); await tester.pumpAndSettle(); RenderBox getCheckboxRenderer() { return tester.renderObject(find.byType(Checkbox)); } expect(getCheckboxRenderer(), paints..drrect(color: colorScheme.primary)); await Future.delayed(const Duration(seconds: 3)); await tester.pumpWidget(buildCheckbox(seedColor: Colors.blue)); await tester.pump(); await Future.delayed(const Duration(seconds: 3)); expect(getCheckboxRenderer(), paints..drrect(color: colorScheme.primary)); }); } ```
| Before | After | | --------------- | --------------- | | | | --- .../lib/src/material/checkbox_theme.dart | 8 +++- .../flutter/lib/src/material/chip_theme.dart | 6 +++ .../test/material/checkbox_theme_test.dart | 41 +++++++++++++++++++ .../test/material/chip_theme_test.dart | 38 +++++++++++++++++ 4 files changed, 92 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/material/checkbox_theme.dart b/packages/flutter/lib/src/material/checkbox_theme.dart index 293f6ddb79..0a46274647 100644 --- a/packages/flutter/lib/src/material/checkbox_theme.dart +++ b/packages/flutter/lib/src/material/checkbox_theme.dart @@ -201,7 +201,13 @@ class CheckboxThemeData with Diagnosticable { if (identical(a, b)) { return a; } - return BorderSide.lerp(a, b, t); + if (a is MaterialStateBorderSide) { + a = a.resolve({}); + } + if (b is MaterialStateBorderSide) { + b = b.resolve({}); + } + return BorderSide.lerp(a!, b!, t); } } diff --git a/packages/flutter/lib/src/material/chip_theme.dart b/packages/flutter/lib/src/material/chip_theme.dart index 76afdf18be..5f0c0d5c0f 100644 --- a/packages/flutter/lib/src/material/chip_theme.dart +++ b/packages/flutter/lib/src/material/chip_theme.dart @@ -546,6 +546,12 @@ class ChipThemeData with Diagnosticable { if (a == null && b == null) { return null; } + if (a is MaterialStateBorderSide) { + a = a.resolve({}); + } + if (b is MaterialStateBorderSide) { + b = b.resolve({}); + } if (a == null) { return BorderSide.lerp(BorderSide(width: 0, color: b!.color.withAlpha(0)), b, t); } diff --git a/packages/flutter/test/material/checkbox_theme_test.dart b/packages/flutter/test/material/checkbox_theme_test.dart index 390c46812f..b907c84356 100644 --- a/packages/flutter/test/material/checkbox_theme_test.dart +++ b/packages/flutter/test/material/checkbox_theme_test.dart @@ -471,6 +471,47 @@ void main() { expect(lerped.shape, const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.5)))); expect(lerped.side, const BorderSide(width: 3.5)); }); + + testWidgets('MaterialStateBorderSide properly lerp in CheckboxThemeData.side', (WidgetTester tester) async { + late ColorScheme colorScheme; + + Widget buildCheckbox({ required Color seedColor }) { + colorScheme = ColorScheme.fromSeed(seedColor: seedColor); + return MaterialApp( + theme: ThemeData( + colorScheme: colorScheme, + checkboxTheme: CheckboxThemeData( + side: MaterialStateBorderSide.resolveWith((Set states) { + return BorderSide( + color: colorScheme.primary, + width: 4.0, + ); + }), + ), + ), + home: Scaffold( + body: Checkbox( + value: false, + onChanged: (_) { }, + ), + ), + ); + } + + await tester.pumpWidget(buildCheckbox(seedColor: Colors.red)); + await tester.pumpAndSettle(); + + RenderBox getCheckboxRendeBox() { + return tester.renderObject(find.byType(Checkbox)); + } + + expect(getCheckboxRendeBox(), paints..drrect(color: colorScheme.primary)); + + await tester.pumpWidget(buildCheckbox(seedColor: Colors.blue)); + await tester.pump(kPressTimeout); + + expect(getCheckboxRendeBox(), paints..drrect(color: colorScheme.primary)); + }); } Future _pointGestureToCheckbox(WidgetTester tester) async { diff --git a/packages/flutter/test/material/chip_theme_test.dart b/packages/flutter/test/material/chip_theme_test.dart index 5d9cbefc42..ac9a551701 100644 --- a/packages/flutter/test/material/chip_theme_test.dart +++ b/packages/flutter/test/material/chip_theme_test.dart @@ -1483,6 +1483,44 @@ void main() { expect(getIconStyle(tester, deleteIcon)?.color, deleteIconColor); }); + // This is a regression test for https://github.com/flutter/flutter/issues/135136. + testWidgets('MaterialStateBorderSide properly lerp in ChipThemeData.side', (WidgetTester tester) async { + late ColorScheme colorScheme; + + Widget buildChip({ required Color seedColor }) { + colorScheme = ColorScheme.fromSeed(seedColor: seedColor); + return MaterialApp( + theme: ThemeData( + colorScheme: colorScheme, + chipTheme: ChipThemeData( + side: MaterialStateBorderSide.resolveWith((Set states) { + return BorderSide( + color: colorScheme.primary, + width: 4.0, + ); + }), + ), + ), + home: const Scaffold( + body: RawChip(label: Text('Chip')), + ), + ); + } + + await tester.pumpWidget(buildChip(seedColor: Colors.red)); + await tester.pumpAndSettle(); + + RenderBox getChipRenderBox() { + return tester.renderObject(find.byType(RawChip)); + } + + expect(getChipRenderBox(), paints..drrect(color: colorScheme.primary)); + + await tester.pumpWidget(buildChip(seedColor: Colors.blue)); + await tester.pump(kPressTimeout); + + expect(getChipRenderBox(), paints..drrect(color: colorScheme.primary)); + }); } class _MaterialStateOutlinedBorder extends StadiumBorder implements MaterialStateOutlinedBorder {