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

<details>
<summary>expand to view the code sample</summary> 

```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<MaterialState> 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<RenderBox>(find.byType(Checkbox));
    }

    expect(getCheckboxRenderer(), paints..drrect(color: colorScheme.primary));

    await Future<void>.delayed(const Duration(seconds: 3));

    await tester.pumpWidget(buildCheckbox(seedColor: Colors.blue));
    await tester.pump();

    await Future<void>.delayed(const Duration(seconds: 3));

    expect(getCheckboxRenderer(), paints..drrect(color: colorScheme.primary));
  });
}
```

</details>

| Before | After |
| --------------- | --------------- |
| <img src="https://github.com/flutter/flutter/assets/48603081/6df34104-37ba-4a82-b5cb-7ed4f887992a" /> | <img src="https://github.com/flutter/flutter/assets/48603081/44359248-a101-46eb-a85a-77f976da5f0f"  /> |
This commit is contained in:
Taha Tesser
2024-05-11 02:37:05 +03:00
committed by GitHub
parent 3e14f18178
commit c386acca54
4 changed files with 92 additions and 1 deletions

View File

@@ -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(<WidgetState>{});
}
if (b is MaterialStateBorderSide) {
b = b.resolve(<WidgetState>{});
}
return BorderSide.lerp(a!, b!, t);
}
}

View File

@@ -546,6 +546,12 @@ class ChipThemeData with Diagnosticable {
if (a == null && b == null) {
return null;
}
if (a is MaterialStateBorderSide) {
a = a.resolve(<WidgetState>{});
}
if (b is MaterialStateBorderSide) {
b = b.resolve(<WidgetState>{});
}
if (a == null) {
return BorderSide.lerp(BorderSide(width: 0, color: b!.color.withAlpha(0)), b, t);
}

View File

@@ -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<MaterialState> 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<RenderBox>(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<void> _pointGestureToCheckbox(WidgetTester tester) async {

View File

@@ -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<MaterialState> 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<RenderBox>(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 {