Fix subtitleTextStyle.color isn't applied to the ListTile.subtitle in Material 2 (#133422)

The difference between header text style and subtitle text style and the reason why it doesn't work is the code difference below. If we make the subtitle text style the same as the title text style it will work

<details>
  <summary>Title Text Style</summary>
  
  ###  All Code
  
  ```dart
  TextStyle titleStyle = titleTextStyle
      ?? tileTheme.titleTextStyle
      ?? defaults.titleTextStyle!;
    final Color? titleColor = effectiveColor;
    titleStyle = titleStyle.copyWith(
      color: titleColor,
      fontSize: _isDenseLayout(theme, tileTheme) ? 13.0 : null,
    );
    final Widget titleText = AnimatedDefaultTextStyle(
      style: titleStyle,
      duration: kThemeChangeDuration,
      child: title ?? const SizedBox(),
    );
  ```
  
  ## Different Code Section
  
  ```dart
  final Color? titleColor = effectiveColor;
  ```
</details>

<details>
  <summary>Subtitle Text Style</summary>
  
  ## All Code
  
  ```dart
  subtitleStyle = subtitleTextStyle
        ?? tileTheme.subtitleTextStyle
        ?? defaults.subtitleTextStyle!;
      final Color? subtitleColor = effectiveColor
        ?? (theme.useMaterial3 ? null : theme.textTheme.bodySmall!.color);
      subtitleStyle = subtitleStyle.copyWith(
        color: subtitleColor,
        fontSize: _isDenseLayout(theme, tileTheme) ? 12.0 : null,
      );
      subtitleText = AnimatedDefaultTextStyle(
        style: subtitleStyle,
        duration: kThemeChangeDuration,
        child: subtitle!,
      );
  ```
  
  ## Different Code Section
  
  ```dart
  final Color? subtitleColor = effectiveColor
        ?? (theme.useMaterial3 ? null : theme.textTheme.bodySmall!.color);
  ```

### Description for code 
- The value `theme.textTheme.bodySmall!.color` is given because the `effectiveColor` value is `null` and the `theme.useMaterial3` value is `false`
</details>

<details>
  <summary>Problem solved code</summary>
  
  ## All Code
  
  ```dart
  subtitleStyle = subtitleTextStyle
        ?? tileTheme.subtitleTextStyle
        ?? defaults.subtitleTextStyle!;
      final Color? subtitleColor = effectiveColor;
      subtitleStyle = subtitleStyle.copyWith(
        color: subtitleColor,
        fontSize: _isDenseLayout(theme, tileTheme) ? 12.0 : null,
      );
      subtitleText = AnimatedDefaultTextStyle(
        style: subtitleStyle,
        duration: kThemeChangeDuration,
        child: subtitle!,
      );
  ```
</details>

<details>
<summary>Screenshot of the result after making the necessary change</summary>
<img src="https://github.com/flutter/flutter/assets/70351342/b552fd4c-fdcd-4bf5-b4ba-d6b2cfe527cc" width=250>
</details>

#133412

*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
This commit is contained in:
Burak İmdat 2023-09-06 21:54:45 +03:00 committed by GitHub
parent b0e5a5ca67
commit cd9a257d74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 207 additions and 28 deletions

View File

@ -801,8 +801,7 @@ class ListTile extends StatelessWidget {
subtitleStyle = subtitleTextStyle
?? tileTheme.subtitleTextStyle
?? defaults.subtitleTextStyle!;
final Color? subtitleColor = effectiveColor
?? (theme.useMaterial3 ? null : theme.textTheme.bodySmall!.color);
final Color? subtitleColor = effectiveColor;
subtitleStyle = subtitleStyle.copyWith(
color: subtitleColor,
fontSize: _isDenseLayout(theme, tileTheme) ? 12.0 : null,
@ -1533,7 +1532,8 @@ class _LisTileDefaultsM2 extends ListTileThemeData {
}
@override
TextStyle? get subtitleTextStyle => _textTheme.bodyMedium;
TextStyle? get subtitleTextStyle => _textTheme.bodyMedium!
.copyWith(color: _textTheme.bodySmall!.color);
@override
TextStyle? get leadingAndTrailingTextStyle => _textTheme.bodyMedium;

View File

@ -393,14 +393,30 @@ void main() {
});
testWidgetsWithLeakTracking(
"ListTile respects ListTileTheme's titleTextStyle, subtitleTextStyle & leadingAndTrailingTextStyle",
"Material3 - ListTile respects ListTileTheme's titleTextStyle, subtitleTextStyle & leadingAndTrailingTextStyle",
(WidgetTester tester) async {
const TextStyle titleTextStyle = TextStyle(
fontSize: 23.0,
color: Color(0xffff0000),
fontStyle: FontStyle.italic,
);
const TextStyle subtitleTextStyle = TextStyle(
fontSize: 20.0,
color: Color(0xff00ff00),
fontStyle: FontStyle.italic,
);
const TextStyle leadingAndTrailingTextStyle = TextStyle(
fontSize: 18.0,
color: Color(0xff0000ff),
fontStyle: FontStyle.italic,
);
final ThemeData theme = ThemeData(
useMaterial3: true,
listTileTheme: const ListTileThemeData(
titleTextStyle: TextStyle(fontSize: 20.0),
subtitleTextStyle: TextStyle(fontSize: 17.5),
leadingAndTrailingTextStyle: TextStyle(fontSize: 15.0),
titleTextStyle: titleTextStyle,
subtitleTextStyle: subtitleTextStyle,
leadingAndTrailingTextStyle: leadingAndTrailingTextStyle,
),
);
@ -426,31 +442,51 @@ void main() {
await tester.pumpWidget(buildFrame());
final RenderParagraph leading = _getTextRenderObject(tester, 'leading');
expect(leading.text.style!.fontSize, 15.0);
expect(leading.text.style!.fontSize, leadingAndTrailingTextStyle.fontSize);
expect(leading.text.style!.color, leadingAndTrailingTextStyle.color);
expect(leading.text.style!.fontStyle, leadingAndTrailingTextStyle.fontStyle);
final RenderParagraph title = _getTextRenderObject(tester, 'title');
expect(title.text.style!.fontSize, 20.0);
expect(title.text.style!.fontSize, titleTextStyle.fontSize);
expect(title.text.style!.color, titleTextStyle.color);
expect(title.text.style!.fontStyle, titleTextStyle.fontStyle);
final RenderParagraph subtitle = _getTextRenderObject(tester, 'subtitle');
expect(subtitle.text.style!.fontSize, 17.5);
expect(subtitle.text.style!.fontSize, subtitleTextStyle.fontSize);
expect(subtitle.text.style!.color, subtitleTextStyle.color);
expect(subtitle.text.style!.fontStyle, subtitleTextStyle.fontStyle);
final RenderParagraph trailing = _getTextRenderObject(tester, 'trailing');
expect(trailing.text.style!.fontSize, 15.0);
expect(trailing.text.style!.fontSize, leadingAndTrailingTextStyle.fontSize);
expect(trailing.text.style!.color, leadingAndTrailingTextStyle.color);
expect(trailing.text.style!.fontStyle, leadingAndTrailingTextStyle.fontStyle);
});
testWidgetsWithLeakTracking(
"ListTile's titleTextStyle, subtitleTextStyle & leadingAndTrailingTextStyle are overridden by ListTile properties",
"Material2 - ListTile respects ListTileTheme's titleTextStyle, subtitleTextStyle & leadingAndTrailingTextStyle",
(WidgetTester tester) async {
const TextStyle titleTextStyle = TextStyle(
fontSize: 23.0,
color: Color(0xffff0000),
fontStyle: FontStyle.italic,
);
const TextStyle subtitleTextStyle = TextStyle(
fontSize: 20.0,
color: Color(0xff00ff00),
fontStyle: FontStyle.italic,
);
const TextStyle leadingAndTrailingTextStyle = TextStyle(
fontSize: 18.0,
color: Color(0xff0000ff),
fontStyle: FontStyle.italic,
);
final ThemeData theme = ThemeData(
useMaterial3: true,
listTileTheme: const ListTileThemeData(
titleTextStyle: TextStyle(fontSize: 20.0),
subtitleTextStyle: TextStyle(fontSize: 17.5),
leadingAndTrailingTextStyle: TextStyle(fontSize: 15.0),
useMaterial3: false,
listTileTheme: const ListTileThemeData(
titleTextStyle: titleTextStyle,
subtitleTextStyle: subtitleTextStyle,
leadingAndTrailingTextStyle: leadingAndTrailingTextStyle,
),
);
const TextStyle titleTextStyle = TextStyle(fontSize: 23.0);
const TextStyle subtitleTextStyle = TextStyle(fontSize: 20.0);
const TextStyle leadingAndTrailingTextStyle = TextStyle(fontSize: 18.0);
Widget buildFrame() {
return MaterialApp(
theme: theme,
@ -459,9 +495,6 @@ void main() {
child: Builder(
builder: (BuildContext context) {
return const ListTile(
titleTextStyle: titleTextStyle,
subtitleTextStyle: subtitleTextStyle,
leadingAndTrailingTextStyle: leadingAndTrailingTextStyle,
leading: TestText('leading'),
title: TestText('title'),
subtitle: TestText('subtitle'),
@ -476,13 +509,159 @@ void main() {
await tester.pumpWidget(buildFrame());
final RenderParagraph leading = _getTextRenderObject(tester, 'leading');
expect(leading.text.style!.fontSize, 18.0);
expect(leading.text.style!.fontSize, leadingAndTrailingTextStyle.fontSize);
expect(leading.text.style!.color, leadingAndTrailingTextStyle.color);
expect(leading.text.style!.fontStyle, leadingAndTrailingTextStyle.fontStyle);
final RenderParagraph title = _getTextRenderObject(tester, 'title');
expect(title.text.style!.fontSize, 23.0);
expect(title.text.style!.fontSize, titleTextStyle.fontSize);
expect(title.text.style!.color, titleTextStyle.color);
expect(title.text.style!.fontStyle, titleTextStyle.fontStyle);
final RenderParagraph subtitle = _getTextRenderObject(tester, 'subtitle');
expect(subtitle.text.style!.fontSize, 20.0);
expect(subtitle.text.style!.fontSize, subtitleTextStyle.fontSize);
expect(subtitle.text.style!.color, subtitleTextStyle.color);
expect(subtitle.text.style!.fontStyle, subtitleTextStyle.fontStyle);
final RenderParagraph trailing = _getTextRenderObject(tester, 'trailing');
expect(trailing.text.style!.fontSize, 18.0);
expect(trailing.text.style!.fontSize, leadingAndTrailingTextStyle.fontSize);
expect(trailing.text.style!.color, leadingAndTrailingTextStyle.color);
expect(trailing.text.style!.fontStyle, leadingAndTrailingTextStyle.fontStyle);
});
testWidgetsWithLeakTracking(
"Material3 - ListTile's titleTextStyle, subtitleTextStyle & leadingAndTrailingTextStyle are overridden by ListTile properties",
(WidgetTester tester) async {
final ThemeData theme = ThemeData(
useMaterial3: true,
listTileTheme: const ListTileThemeData(
titleTextStyle: TextStyle(fontSize: 20.0),
subtitleTextStyle: TextStyle(fontSize: 17.5),
leadingAndTrailingTextStyle: TextStyle(fontSize: 15.0),
),
);
const TextStyle titleTextStyle = TextStyle(
fontSize: 23.0,
color: Color(0xffff0000),
fontStyle: FontStyle.italic,
);
const TextStyle subtitleTextStyle = TextStyle(
fontSize: 20.0,
color: Color(0xff00ff00),
fontStyle: FontStyle.italic,
);
const TextStyle leadingAndTrailingTextStyle = TextStyle(
fontSize: 18.0,
color: Color(0xff0000ff),
fontStyle: FontStyle.italic,
);
Widget buildFrame() {
return MaterialApp(
theme: theme,
home: Material(
child: Center(
child: Builder(
builder: (BuildContext context) {
return const ListTile(
titleTextStyle: titleTextStyle,
subtitleTextStyle: subtitleTextStyle,
leadingAndTrailingTextStyle: leadingAndTrailingTextStyle,
leading: TestText('leading'),
title: TestText('title'),
subtitle: TestText('subtitle'),
trailing: TestText('trailing'),
);
},
),
),
),
);
}
await tester.pumpWidget(buildFrame());
final RenderParagraph leading = _getTextRenderObject(tester, 'leading');
expect(leading.text.style!.fontSize, leadingAndTrailingTextStyle.fontSize);
expect(leading.text.style!.color, leadingAndTrailingTextStyle.color);
expect(leading.text.style!.fontStyle, leadingAndTrailingTextStyle.fontStyle);
final RenderParagraph title = _getTextRenderObject(tester, 'title');
expect(title.text.style!.fontSize, titleTextStyle.fontSize);
expect(title.text.style!.color, titleTextStyle.color);
expect(title.text.style!.fontStyle, titleTextStyle.fontStyle);
final RenderParagraph subtitle = _getTextRenderObject(tester, 'subtitle');
expect(subtitle.text.style!.fontSize, subtitleTextStyle.fontSize);
expect(subtitle.text.style!.color, subtitleTextStyle.color);
expect(subtitle.text.style!.fontStyle, subtitleTextStyle.fontStyle);
final RenderParagraph trailing = _getTextRenderObject(tester, 'trailing');
expect(trailing.text.style!.fontSize, leadingAndTrailingTextStyle.fontSize);
expect(trailing.text.style!.color, leadingAndTrailingTextStyle.color);
expect(trailing.text.style!.fontStyle, leadingAndTrailingTextStyle.fontStyle);
});
testWidgetsWithLeakTracking(
"Material2 - ListTile's titleTextStyle, subtitleTextStyle & leadingAndTrailingTextStyle are overridden by ListTile properties",
(WidgetTester tester) async {
final ThemeData theme = ThemeData(
useMaterial3: false,
listTileTheme: const ListTileThemeData(
titleTextStyle: TextStyle(fontSize: 20.0),
subtitleTextStyle: TextStyle(fontSize: 17.5),
leadingAndTrailingTextStyle: TextStyle(fontSize: 15.0),
),
);
const TextStyle titleTextStyle = TextStyle(
fontSize: 23.0,
color: Color(0xffff0000),
fontStyle: FontStyle.italic,
);
const TextStyle subtitleTextStyle = TextStyle(
fontSize: 20.0,
color: Color(0xff00ff00),
fontStyle: FontStyle.italic,
);
const TextStyle leadingAndTrailingTextStyle = TextStyle(
fontSize: 18.0,
color: Color(0xff0000ff),
fontStyle: FontStyle.italic,
);
Widget buildFrame() {
return MaterialApp(
theme: theme,
home: Material(
child: Center(
child: Builder(
builder: (BuildContext context) {
return const ListTile(
titleTextStyle: titleTextStyle,
subtitleTextStyle: subtitleTextStyle,
leadingAndTrailingTextStyle: leadingAndTrailingTextStyle,
leading: TestText('leading'),
title: TestText('title'),
subtitle: TestText('subtitle'),
trailing: TestText('trailing'),
);
},
),
),
),
);
}
await tester.pumpWidget(buildFrame());
final RenderParagraph leading = _getTextRenderObject(tester, 'leading');
expect(leading.text.style!.fontSize, leadingAndTrailingTextStyle.fontSize);
expect(leading.text.style!.color, leadingAndTrailingTextStyle.color);
expect(leading.text.style!.fontStyle, leadingAndTrailingTextStyle.fontStyle);
final RenderParagraph title = _getTextRenderObject(tester, 'title');
expect(title.text.style!.fontSize, titleTextStyle.fontSize);
expect(title.text.style!.color, titleTextStyle.color);
expect(title.text.style!.fontStyle, titleTextStyle.fontStyle);
final RenderParagraph subtitle = _getTextRenderObject(tester, 'subtitle');
expect(subtitle.text.style!.fontSize, subtitleTextStyle.fontSize);
expect(subtitle.text.style!.color, subtitleTextStyle.color);
expect(subtitle.text.style!.fontStyle, subtitleTextStyle.fontStyle);
final RenderParagraph trailing = _getTextRenderObject(tester, 'trailing');
expect(trailing.text.style!.fontSize, leadingAndTrailingTextStyle.fontSize);
expect(trailing.text.style!.color, leadingAndTrailingTextStyle.color);
expect(trailing.text.style!.fontStyle, leadingAndTrailingTextStyle.fontStyle);
});
testWidgetsWithLeakTracking("ListTile respects ListTileTheme's tileColor & selectedTileColor", (WidgetTester tester) async {