mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
feat(RadioListTile):ensure that 'isThreeLine' can be configured through the (#166964)
This PR is a continuation of [165481](https://github.com/flutter/flutter/pull/165481) Related items also include: [SwitchListTile](https://github.com/flutter/flutter/pull/166820), [CheckboxListTile](https://github.com/flutter/flutter/pull/166826) ## 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. --------- Co-authored-by: Tong Mu <dkwingsmt@users.noreply.github.com>
This commit is contained in:
parent
0d2ee2c49c
commit
dfd0a3cb5f
@ -140,7 +140,8 @@ class ListTileThemeData with Diagnosticable {
|
||||
/// or [ExpansionTile.controlAffinity] or [SwitchListTile.controlAffinity] or [RadioListTile.controlAffinity].
|
||||
final ListTileControlAffinity? controlAffinity;
|
||||
|
||||
/// If specified, overrides the default value of [ListTile.isThreeLine] or [CheckboxListTile.isThreeLine].
|
||||
/// If specified, overrides the default value of [ListTile.isThreeLine] or [CheckboxListTile.isThreeLine]
|
||||
/// or [RadioListTile.isThreeLine].
|
||||
final bool? isThreeLine;
|
||||
|
||||
/// Creates a copy of this object with the given fields replaced with the
|
||||
|
||||
@ -186,7 +186,7 @@ class RadioListTile<T> extends StatelessWidget {
|
||||
this.materialTapTargetSize,
|
||||
this.title,
|
||||
this.subtitle,
|
||||
this.isThreeLine = false,
|
||||
this.isThreeLine,
|
||||
this.dense,
|
||||
this.secondary,
|
||||
this.selected = false,
|
||||
@ -204,7 +204,7 @@ class RadioListTile<T> extends StatelessWidget {
|
||||
this.internalAddSemanticForOnTap = false,
|
||||
}) : _radioType = _RadioType.material,
|
||||
useCupertinoCheckmarkStyle = false,
|
||||
assert(!isThreeLine || subtitle != null);
|
||||
assert(isThreeLine != true || subtitle != null);
|
||||
|
||||
/// Creates a combination of a list tile and a platform adaptive radio.
|
||||
///
|
||||
@ -227,7 +227,7 @@ class RadioListTile<T> extends StatelessWidget {
|
||||
this.materialTapTargetSize,
|
||||
this.title,
|
||||
this.subtitle,
|
||||
this.isThreeLine = false,
|
||||
this.isThreeLine,
|
||||
this.dense,
|
||||
this.secondary,
|
||||
this.selected = false,
|
||||
@ -245,7 +245,7 @@ class RadioListTile<T> extends StatelessWidget {
|
||||
this.useCupertinoCheckmarkStyle = false,
|
||||
this.internalAddSemanticForOnTap = false,
|
||||
}) : _radioType = _RadioType.adaptive,
|
||||
assert(!isThreeLine || subtitle != null);
|
||||
assert(isThreeLine != true || subtitle != null);
|
||||
|
||||
/// The value represented by this radio button.
|
||||
final T value;
|
||||
@ -385,9 +385,10 @@ class RadioListTile<T> extends StatelessWidget {
|
||||
|
||||
/// Whether this list tile is intended to display three lines of text.
|
||||
///
|
||||
/// If false, the list tile is treated as having one line if the subtitle is
|
||||
/// null and treated as having two lines if the subtitle is non-null.
|
||||
final bool isThreeLine;
|
||||
/// If null, the value from [ListTileThemeData.isThreeLine] is used.
|
||||
/// If that is also null, the value from [ThemeData.listTileTheme] is used.
|
||||
/// If still null, the default value is `false`.
|
||||
final bool? isThreeLine;
|
||||
|
||||
/// Whether this list tile is part of a vertically dense list.
|
||||
///
|
||||
|
||||
@ -1645,4 +1645,239 @@ void main() {
|
||||
|
||||
expect(widget.transform.getMaxScaleOnAxis(), scale);
|
||||
});
|
||||
|
||||
testWidgets('RadioListTile isThreeLine', (WidgetTester tester) async {
|
||||
const double height = 300;
|
||||
const double size = 40.0;
|
||||
|
||||
Widget buildFrame({bool? themeDataIsThreeLine, bool? themeIsThreeLine, bool? isThreeLine}) {
|
||||
return MaterialApp(
|
||||
key: UniqueKey(),
|
||||
theme:
|
||||
themeDataIsThreeLine != null
|
||||
? ThemeData(listTileTheme: ListTileThemeData(isThreeLine: themeDataIsThreeLine))
|
||||
: null,
|
||||
home: Material(
|
||||
child: ListTileTheme(
|
||||
data:
|
||||
themeIsThreeLine != null ? ListTileThemeData(isThreeLine: themeIsThreeLine) : null,
|
||||
child: ListView(
|
||||
children: <Widget>[
|
||||
RadioListTile<int>(
|
||||
isThreeLine: isThreeLine,
|
||||
title: const Text('A'),
|
||||
subtitle: const Text('A\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM'),
|
||||
value: 0,
|
||||
onChanged: null,
|
||||
groupValue: 1,
|
||||
),
|
||||
RadioListTile<int>(
|
||||
isThreeLine: isThreeLine,
|
||||
title: const Text('A'),
|
||||
subtitle: const Text('A'),
|
||||
value: 0,
|
||||
onChanged: null,
|
||||
groupValue: 2,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void expectTwoLine() {
|
||||
expect(
|
||||
tester.getRect(find.byType(RadioListTile<int>).at(0)),
|
||||
const Rect.fromLTWH(0.0, 0.0, 800.0, height),
|
||||
);
|
||||
expect(
|
||||
tester.getRect(find.byType(Radio<int>).at(0)),
|
||||
const Rect.fromLTWH(16.0, 130.0, size, size),
|
||||
);
|
||||
expect(
|
||||
tester.getRect(find.byType(RadioListTile<int>).at(1)),
|
||||
const Rect.fromLTWH(0.0, height, 800.0, 72.0),
|
||||
);
|
||||
expect(
|
||||
tester.getRect(find.byType(Radio<int>).at(1)),
|
||||
const Rect.fromLTWH(16.0, height + 16, size, size),
|
||||
);
|
||||
}
|
||||
|
||||
void expectThreeLine() {
|
||||
expect(
|
||||
tester.getRect(find.byType(RadioListTile<int>).at(0)),
|
||||
const Rect.fromLTWH(0.0, 0.0, 800.0, height),
|
||||
);
|
||||
expect(
|
||||
tester.getRect(find.byType(Radio<int>).at(0)),
|
||||
const Rect.fromLTWH(16.0, 8.0, size, size),
|
||||
);
|
||||
expect(
|
||||
tester.getRect(find.byType(RadioListTile<int>).at(1)),
|
||||
const Rect.fromLTWH(0.0, height, 800.0, 88.0),
|
||||
);
|
||||
expect(
|
||||
tester.getRect(find.byType(Radio<int>).at(1)),
|
||||
const Rect.fromLTWH(16.0, height + 8.0, size, size),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildFrame());
|
||||
expectTwoLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(themeDataIsThreeLine: true));
|
||||
expectThreeLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(themeDataIsThreeLine: false, themeIsThreeLine: true));
|
||||
expectThreeLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(themeDataIsThreeLine: true, themeIsThreeLine: false));
|
||||
expectTwoLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(isThreeLine: true));
|
||||
expectThreeLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(themeIsThreeLine: true, isThreeLine: false));
|
||||
expectTwoLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(themeDataIsThreeLine: true, isThreeLine: false));
|
||||
expectTwoLine();
|
||||
|
||||
await tester.pumpWidget(
|
||||
buildFrame(themeDataIsThreeLine: true, themeIsThreeLine: true, isThreeLine: false),
|
||||
);
|
||||
expectTwoLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(themeIsThreeLine: false, isThreeLine: true));
|
||||
expectThreeLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(themeDataIsThreeLine: false, isThreeLine: true));
|
||||
expectThreeLine();
|
||||
|
||||
await tester.pumpWidget(
|
||||
buildFrame(themeDataIsThreeLine: false, themeIsThreeLine: false, isThreeLine: true),
|
||||
);
|
||||
expectThreeLine();
|
||||
});
|
||||
|
||||
testWidgets('RadioListTile.adaptive isThreeLine', (WidgetTester tester) async {
|
||||
const double height = 300;
|
||||
const double size = 18.0;
|
||||
|
||||
Widget buildFrame({bool? themeDataIsThreeLine, bool? themeIsThreeLine, bool? isThreeLine}) {
|
||||
return MaterialApp(
|
||||
key: UniqueKey(),
|
||||
theme: ThemeData(
|
||||
platform: TargetPlatform.iOS,
|
||||
listTileTheme:
|
||||
themeDataIsThreeLine != null
|
||||
? ListTileThemeData(isThreeLine: themeDataIsThreeLine)
|
||||
: null,
|
||||
),
|
||||
home: Material(
|
||||
child: ListTileTheme(
|
||||
data:
|
||||
themeIsThreeLine != null ? ListTileThemeData(isThreeLine: themeIsThreeLine) : null,
|
||||
child: ListView(
|
||||
children: <Widget>[
|
||||
RadioListTile<int>.adaptive(
|
||||
isThreeLine: isThreeLine,
|
||||
title: const Text('A'),
|
||||
subtitle: const Text('A\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM'),
|
||||
value: 0,
|
||||
onChanged: null,
|
||||
groupValue: 1,
|
||||
),
|
||||
RadioListTile<int>.adaptive(
|
||||
isThreeLine: isThreeLine,
|
||||
title: const Text('A'),
|
||||
subtitle: const Text('A'),
|
||||
value: 0,
|
||||
onChanged: null,
|
||||
groupValue: 2,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void expectTwoLine() {
|
||||
expect(
|
||||
tester.getRect(find.byType(RadioListTile<int>).at(0)),
|
||||
const Rect.fromLTWH(0.0, 0.0, 800.0, height),
|
||||
);
|
||||
expect(
|
||||
tester.getRect(find.byType(Radio<int>).at(0)),
|
||||
const Rect.fromLTWH(16.0, 141.0, size, size),
|
||||
);
|
||||
expect(
|
||||
tester.getRect(find.byType(RadioListTile<int>).at(1)),
|
||||
const Rect.fromLTWH(0.0, height, 800.0, 72.0),
|
||||
);
|
||||
expect(
|
||||
tester.getRect(find.byType(Radio<int>).at(1)),
|
||||
const Rect.fromLTWH(16.0, height + 27.0, size, size),
|
||||
);
|
||||
}
|
||||
|
||||
void expectThreeLine() {
|
||||
expect(
|
||||
tester.getRect(find.byType(RadioListTile<int>).at(0)),
|
||||
const Rect.fromLTWH(0.0, 0.0, 800.0, height),
|
||||
);
|
||||
expect(
|
||||
tester.getRect(find.byType(Radio<int>).at(0)),
|
||||
const Rect.fromLTWH(16.0, 8.0, size, size),
|
||||
);
|
||||
expect(
|
||||
tester.getRect(find.byType(RadioListTile<int>).at(1)),
|
||||
const Rect.fromLTWH(0.0, height, 800.0, 88.0),
|
||||
);
|
||||
expect(
|
||||
tester.getRect(find.byType(Radio<int>).at(1)),
|
||||
const Rect.fromLTWH(16.0, height + 8.0, size, size),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildFrame());
|
||||
expectTwoLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(themeDataIsThreeLine: true));
|
||||
expectThreeLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(themeDataIsThreeLine: false, themeIsThreeLine: true));
|
||||
expectThreeLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(themeDataIsThreeLine: true, themeIsThreeLine: false));
|
||||
expectTwoLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(isThreeLine: true));
|
||||
expectThreeLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(themeIsThreeLine: true, isThreeLine: false));
|
||||
expectTwoLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(themeDataIsThreeLine: true, isThreeLine: false));
|
||||
expectTwoLine();
|
||||
|
||||
await tester.pumpWidget(
|
||||
buildFrame(themeDataIsThreeLine: true, themeIsThreeLine: true, isThreeLine: false),
|
||||
);
|
||||
expectTwoLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(themeIsThreeLine: false, isThreeLine: true));
|
||||
expectThreeLine();
|
||||
|
||||
await tester.pumpWidget(buildFrame(themeDataIsThreeLine: false, isThreeLine: true));
|
||||
expectThreeLine();
|
||||
|
||||
await tester.pumpWidget(
|
||||
buildFrame(themeDataIsThreeLine: false, themeIsThreeLine: false, isThreeLine: true),
|
||||
);
|
||||
expectThreeLine();
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user