mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add backgroundColor to RadioThemeData (#171326)
Part of https://github.com/flutter/flutter/issues/168787 Follow-up of https://github.com/flutter/flutter/pull/171204 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
parent
10298edaab
commit
bf3e8566eb
@ -88,6 +88,10 @@ class _RadioDefaultsM3 extends RadioThemeData {
|
||||
|
||||
@override
|
||||
VisualDensity get visualDensity => _theme.visualDensity;
|
||||
|
||||
@override
|
||||
WidgetStateProperty<Color> get backgroundColor =>
|
||||
WidgetStateProperty.all<Color>(Colors.transparent);
|
||||
}
|
||||
''';
|
||||
}
|
||||
|
||||
@ -418,6 +418,7 @@ class Radio<T> extends StatefulWidget {
|
||||
/// {@endtemplate}
|
||||
final bool? enabled;
|
||||
|
||||
/// {@template flutter.material.Radio.backgroundColor}
|
||||
/// The color of the background of the radio button, in all [WidgetState]s.
|
||||
///
|
||||
/// Resolves in the following states:
|
||||
@ -427,6 +428,7 @@ class Radio<T> extends StatefulWidget {
|
||||
/// * [WidgetState.disabled].
|
||||
///
|
||||
/// If null, then it is transparent in all states.
|
||||
/// {@endtemplate}
|
||||
final WidgetStateProperty<Color?>? backgroundColor;
|
||||
|
||||
/// The side for the circular border of the radio button, in all
|
||||
@ -673,11 +675,14 @@ class _RadioPaintState extends State<_RadioPaint> {
|
||||
radioTheme.fillColor?.resolve(inactiveStates);
|
||||
final Color effectiveInactiveColor =
|
||||
inactiveColor ?? defaults.fillColor!.resolve(inactiveStates)!;
|
||||
// TODO(ValentinVignal): Add backgroundColor to RadioThemeData.
|
||||
final Color activeBackgroundColor =
|
||||
widget.backgroundColor?.resolve(activeStates) ?? Colors.transparent;
|
||||
widget.backgroundColor?.resolve(activeStates) ??
|
||||
radioTheme.backgroundColor?.resolve(activeStates) ??
|
||||
defaults.backgroundColor!.resolve(activeStates)!;
|
||||
final Color inactiveBackgroundColor =
|
||||
widget.backgroundColor?.resolve(inactiveStates) ?? Colors.transparent;
|
||||
widget.backgroundColor?.resolve(inactiveStates) ??
|
||||
radioTheme.backgroundColor?.resolve(inactiveStates) ??
|
||||
defaults.backgroundColor!.resolve(inactiveStates)!;
|
||||
|
||||
final Set<MaterialState> focusedStates =
|
||||
widget.toggleableState.states..add(MaterialState.focused);
|
||||
@ -908,6 +913,10 @@ class _RadioDefaultsM2 extends RadioThemeData {
|
||||
|
||||
@override
|
||||
VisualDensity get visualDensity => _theme.visualDensity;
|
||||
|
||||
@override
|
||||
WidgetStateProperty<Color> get backgroundColor =>
|
||||
WidgetStateProperty.all<Color>(Colors.transparent);
|
||||
}
|
||||
|
||||
// BEGIN GENERATED TOKEN PROPERTIES - Radio<T>
|
||||
@ -992,6 +1001,10 @@ class _RadioDefaultsM3 extends RadioThemeData {
|
||||
|
||||
@override
|
||||
VisualDensity get visualDensity => _theme.visualDensity;
|
||||
|
||||
@override
|
||||
WidgetStateProperty<Color> get backgroundColor =>
|
||||
WidgetStateProperty.all<Color>(Colors.transparent);
|
||||
}
|
||||
// dart format on
|
||||
|
||||
|
||||
@ -49,6 +49,7 @@ class RadioThemeData with Diagnosticable {
|
||||
this.splashRadius,
|
||||
this.materialTapTargetSize,
|
||||
this.visualDensity,
|
||||
this.backgroundColor,
|
||||
});
|
||||
|
||||
/// {@macro flutter.widget.RawRadio.mouseCursor}
|
||||
@ -86,6 +87,9 @@ class RadioThemeData with Diagnosticable {
|
||||
/// default value is the value of [ThemeData.visualDensity].
|
||||
final VisualDensity? visualDensity;
|
||||
|
||||
/// {@macro flutter.material.Radio.backgroundColor}
|
||||
final WidgetStateProperty<Color?>? backgroundColor;
|
||||
|
||||
/// Creates a copy of this object but with the given fields replaced with the
|
||||
/// new values.
|
||||
RadioThemeData copyWith({
|
||||
@ -95,6 +99,7 @@ class RadioThemeData with Diagnosticable {
|
||||
double? splashRadius,
|
||||
MaterialTapTargetSize? materialTapTargetSize,
|
||||
VisualDensity? visualDensity,
|
||||
WidgetStateProperty<Color?>? backgroundColor,
|
||||
}) {
|
||||
return RadioThemeData(
|
||||
mouseCursor: mouseCursor ?? this.mouseCursor,
|
||||
@ -103,6 +108,7 @@ class RadioThemeData with Diagnosticable {
|
||||
splashRadius: splashRadius ?? this.splashRadius,
|
||||
materialTapTargetSize: materialTapTargetSize ?? this.materialTapTargetSize,
|
||||
visualDensity: visualDensity ?? this.visualDensity,
|
||||
backgroundColor: backgroundColor ?? this.backgroundColor,
|
||||
);
|
||||
}
|
||||
|
||||
@ -125,6 +131,12 @@ class RadioThemeData with Diagnosticable {
|
||||
),
|
||||
splashRadius: lerpDouble(a?.splashRadius, b?.splashRadius, t),
|
||||
visualDensity: t < 0.5 ? a?.visualDensity : b?.visualDensity,
|
||||
backgroundColor: WidgetStateProperty.lerp<Color?>(
|
||||
a?.backgroundColor,
|
||||
b?.backgroundColor,
|
||||
t,
|
||||
Color.lerp,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -136,6 +148,7 @@ class RadioThemeData with Diagnosticable {
|
||||
splashRadius,
|
||||
materialTapTargetSize,
|
||||
visualDensity,
|
||||
backgroundColor,
|
||||
);
|
||||
|
||||
@override
|
||||
@ -152,7 +165,8 @@ class RadioThemeData with Diagnosticable {
|
||||
other.overlayColor == overlayColor &&
|
||||
other.splashRadius == splashRadius &&
|
||||
other.materialTapTargetSize == materialTapTargetSize &&
|
||||
other.visualDensity == visualDensity;
|
||||
other.visualDensity == visualDensity &&
|
||||
other.backgroundColor == backgroundColor;
|
||||
}
|
||||
|
||||
@override
|
||||
@ -190,6 +204,13 @@ class RadioThemeData with Diagnosticable {
|
||||
properties.add(
|
||||
DiagnosticsProperty<VisualDensity>('visualDensity', visualDensity, defaultValue: null),
|
||||
);
|
||||
properties.add(
|
||||
DiagnosticsProperty<WidgetStateProperty<Color?>>(
|
||||
'backgroundColor',
|
||||
backgroundColor,
|
||||
defaultValue: null,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -27,6 +27,7 @@ void main() {
|
||||
expect(themeData.splashRadius, null);
|
||||
expect(themeData.materialTapTargetSize, null);
|
||||
expect(themeData.visualDensity, null);
|
||||
expect(themeData.backgroundColor, null);
|
||||
|
||||
const RadioTheme theme = RadioTheme(data: RadioThemeData(), child: SizedBox());
|
||||
expect(theme.data.mouseCursor, null);
|
||||
@ -35,6 +36,7 @@ void main() {
|
||||
expect(theme.data.splashRadius, null);
|
||||
expect(theme.data.materialTapTargetSize, null);
|
||||
expect(theme.data.visualDensity, null);
|
||||
expect(theme.data.backgroundColor, null);
|
||||
});
|
||||
|
||||
testWidgets('Default RadioThemeData debugFillProperties', (WidgetTester tester) async {
|
||||
@ -47,18 +49,19 @@ void main() {
|
||||
.map((DiagnosticsNode node) => node.toString())
|
||||
.toList();
|
||||
|
||||
expect(description, <String>[]);
|
||||
expect(description, const <String>[]);
|
||||
});
|
||||
|
||||
testWidgets('RadioThemeData implements debugFillProperties', (WidgetTester tester) async {
|
||||
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
||||
const RadioThemeData(
|
||||
mouseCursor: MaterialStatePropertyAll<MouseCursor>(SystemMouseCursors.click),
|
||||
fillColor: MaterialStatePropertyAll<Color>(Color(0xfffffff0)),
|
||||
overlayColor: MaterialStatePropertyAll<Color>(Color(0xfffffff1)),
|
||||
mouseCursor: WidgetStatePropertyAll<MouseCursor>(SystemMouseCursors.click),
|
||||
fillColor: WidgetStatePropertyAll<Color>(Color(0xfffffff0)),
|
||||
overlayColor: WidgetStatePropertyAll<Color>(Color(0xfffffff1)),
|
||||
splashRadius: 1.0,
|
||||
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
visualDensity: VisualDensity.standard,
|
||||
backgroundColor: WidgetStatePropertyAll<Color>(Color(0xfffffff2)),
|
||||
).debugFillProperties(builder);
|
||||
|
||||
final List<String> description =
|
||||
@ -76,6 +79,7 @@ void main() {
|
||||
'splashRadius: 1.0',
|
||||
'materialTapTargetSize: MaterialTapTargetSize.shrinkWrap',
|
||||
'visualDensity: VisualDensity#00000(h: 0.0, v: 0.0)',
|
||||
'backgroundColor: WidgetStatePropertyAll(${const Color(0xfffffff2)})',
|
||||
]),
|
||||
);
|
||||
});
|
||||
@ -88,6 +92,8 @@ void main() {
|
||||
const Color selectedFillColor = Color(0xfffffff1);
|
||||
const Color focusOverlayColor = Color(0xfffffff2);
|
||||
const Color hoverOverlayColor = Color(0xfffffff3);
|
||||
const Color defaultBackgroundColor = Color(0xfffffff4);
|
||||
const Color selectedBackgroundColor = Color(0xfffffff5);
|
||||
const double splashRadius = 1.0;
|
||||
const MaterialTapTargetSize materialTapTargetSize = MaterialTapTargetSize.shrinkWrap;
|
||||
const VisualDensity visualDensity = VisualDensity(horizontal: 1, vertical: 1);
|
||||
@ -96,18 +102,18 @@ void main() {
|
||||
return MaterialApp(
|
||||
theme: ThemeData(
|
||||
radioTheme: RadioThemeData(
|
||||
mouseCursor: const MaterialStatePropertyAll<MouseCursor>(mouseCursor),
|
||||
fillColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.selected)) {
|
||||
mouseCursor: const WidgetStatePropertyAll<MouseCursor>(mouseCursor),
|
||||
fillColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return selectedFillColor;
|
||||
}
|
||||
return defaultFillColor;
|
||||
}),
|
||||
overlayColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.focused)) {
|
||||
overlayColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
||||
if (states.contains(WidgetState.focused)) {
|
||||
return focusOverlayColor;
|
||||
}
|
||||
if (states.contains(MaterialState.hovered)) {
|
||||
if (states.contains(WidgetState.hovered)) {
|
||||
return hoverOverlayColor;
|
||||
}
|
||||
return null;
|
||||
@ -115,6 +121,12 @@ void main() {
|
||||
splashRadius: splashRadius,
|
||||
materialTapTargetSize: materialTapTargetSize,
|
||||
visualDensity: visualDensity,
|
||||
backgroundColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return selectedBackgroundColor;
|
||||
}
|
||||
return defaultBackgroundColor;
|
||||
}),
|
||||
),
|
||||
),
|
||||
home: Scaffold(
|
||||
@ -134,7 +146,7 @@ void main() {
|
||||
expect(
|
||||
_getRadioMaterial(tester),
|
||||
paints
|
||||
..circle(color: Colors.transparent)
|
||||
..circle(color: defaultBackgroundColor)
|
||||
..circle(color: defaultFillColor),
|
||||
);
|
||||
// Size from MaterialTapTargetSize.shrinkWrap with added VisualDensity.
|
||||
@ -146,7 +158,7 @@ void main() {
|
||||
expect(
|
||||
_getRadioMaterial(tester),
|
||||
paints
|
||||
..circle(color: Colors.transparent)
|
||||
..circle(color: selectedBackgroundColor)
|
||||
..circle(color: selectedFillColor),
|
||||
);
|
||||
|
||||
@ -177,6 +189,8 @@ void main() {
|
||||
const Color themeSelectedFillColor = Color(0xfffffff1);
|
||||
const Color themeFocusOverlayColor = Color(0xfffffff2);
|
||||
const Color themeHoverOverlayColor = Color(0xfffffff3);
|
||||
const Color themeDefaultBackgroundColor = Color(0xfffffff4);
|
||||
const Color themeSelectedBackgroundColor = Color(0xfffffff5);
|
||||
const double themeSplashRadius = 1.0;
|
||||
const MaterialTapTargetSize themeMaterialTapTargetSize = MaterialTapTargetSize.padded;
|
||||
const VisualDensity themeVisualDensity = VisualDensity.standard;
|
||||
@ -186,6 +200,8 @@ void main() {
|
||||
const Color selectedFillColor = Color(0xfffffff1);
|
||||
const Color focusColor = Color(0xfffffff2);
|
||||
const Color hoverColor = Color(0xfffffff3);
|
||||
const Color defaultBackgroundColor = Color(0xfffffff4);
|
||||
const Color selectedBackgroundColor = Color(0xfffffff5);
|
||||
const double splashRadius = 2.0;
|
||||
const MaterialTapTargetSize materialTapTargetSize = MaterialTapTargetSize.shrinkWrap;
|
||||
const VisualDensity visualDensity = VisualDensity(horizontal: 1, vertical: 1);
|
||||
@ -194,18 +210,18 @@ void main() {
|
||||
return MaterialApp(
|
||||
theme: ThemeData(
|
||||
radioTheme: RadioThemeData(
|
||||
mouseCursor: const MaterialStatePropertyAll<MouseCursor>(themeMouseCursor),
|
||||
fillColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.selected)) {
|
||||
mouseCursor: const WidgetStatePropertyAll<MouseCursor>(themeMouseCursor),
|
||||
fillColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return themeSelectedFillColor;
|
||||
}
|
||||
return themeDefaultFillColor;
|
||||
}),
|
||||
overlayColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.focused)) {
|
||||
overlayColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
||||
if (states.contains(WidgetState.focused)) {
|
||||
return themeFocusOverlayColor;
|
||||
}
|
||||
if (states.contains(MaterialState.hovered)) {
|
||||
if (states.contains(WidgetState.hovered)) {
|
||||
return themeHoverOverlayColor;
|
||||
}
|
||||
return null;
|
||||
@ -213,6 +229,12 @@ void main() {
|
||||
splashRadius: themeSplashRadius,
|
||||
materialTapTargetSize: themeMaterialTapTargetSize,
|
||||
visualDensity: themeVisualDensity,
|
||||
backgroundColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return themeSelectedBackgroundColor;
|
||||
}
|
||||
return themeDefaultBackgroundColor;
|
||||
}),
|
||||
),
|
||||
),
|
||||
home: Scaffold(
|
||||
@ -222,8 +244,8 @@ void main() {
|
||||
groupValue: 0,
|
||||
autofocus: autofocus,
|
||||
mouseCursor: mouseCursor,
|
||||
fillColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
|
||||
if (states.contains(MaterialState.selected)) {
|
||||
fillColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return selectedFillColor;
|
||||
}
|
||||
return defaultFillColor;
|
||||
@ -233,6 +255,12 @@ void main() {
|
||||
splashRadius: splashRadius,
|
||||
materialTapTargetSize: materialTapTargetSize,
|
||||
visualDensity: visualDensity,
|
||||
backgroundColor: WidgetStateProperty.resolveWith((Set<WidgetState> states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return selectedBackgroundColor;
|
||||
}
|
||||
return defaultBackgroundColor;
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -244,7 +272,7 @@ void main() {
|
||||
expect(
|
||||
_getRadioMaterial(tester),
|
||||
paints
|
||||
..circle(color: Colors.transparent)
|
||||
..circle(color: defaultBackgroundColor)
|
||||
..circle(color: defaultFillColor),
|
||||
);
|
||||
// Size from MaterialTapTargetSize.shrinkWrap with added VisualDensity.
|
||||
@ -256,7 +284,7 @@ void main() {
|
||||
expect(
|
||||
_getRadioMaterial(tester),
|
||||
paints
|
||||
..circle(color: Colors.transparent)
|
||||
..circle(color: selectedBackgroundColor)
|
||||
..circle(color: selectedFillColor),
|
||||
);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user