Unverified Commit 8b63c654 authored by Ayush Bherwani's avatar Ayush Bherwani Committed by GitHub

[SwitchListTile] adds controlAffinity property (#58037)

parent 3373a404
...@@ -56,3 +56,4 @@ Michael Lee <ckmichael8@gmail.com> ...@@ -56,3 +56,4 @@ Michael Lee <ckmichael8@gmail.com>
Katarina Sheremet <katarina@sheremet.ch> Katarina Sheremet <katarina@sheremet.ch>
Nicolas Schneider <nioncode+git@gmail.com> Nicolas Schneider <nioncode+git@gmail.com>
Mikhail Zotyev <mbixjkee1392@gmail.com> Mikhail Zotyev <mbixjkee1392@gmail.com>
Ayush Bherwani <ayush.bherwani1998@gmail.com>
...@@ -148,6 +148,7 @@ class ListTileTheme extends InheritedTheme { ...@@ -148,6 +148,7 @@ class ListTileTheme extends InheritedTheme {
/// ///
/// * [CheckboxListTile], which combines a [ListTile] with a [Checkbox]. /// * [CheckboxListTile], which combines a [ListTile] with a [Checkbox].
/// * [RadioListTile], which combines a [ListTile] with a [Radio] button. /// * [RadioListTile], which combines a [ListTile] with a [Radio] button.
/// * [SwitchListTile], which combines a [ListTile] with a [Switch].
enum ListTileControlAffinity { enum ListTileControlAffinity {
/// Position the control on the leading edge, and the secondary widget, if /// Position the control on the leading edge, and the secondary widget, if
/// any, on the trailing edge. /// any, on the trailing edge.
......
...@@ -39,9 +39,8 @@ enum _SwitchListTileType { material, adaptive } ...@@ -39,9 +39,8 @@ enum _SwitchListTileType { material, adaptive }
/// appear selected when the switch is on, pass the same value to both. /// appear selected when the switch is on, pass the same value to both.
/// ///
/// The switch is shown on the right by default in left-to-right languages (i.e. /// The switch is shown on the right by default in left-to-right languages (i.e.
/// in the [ListTile.trailing] slot). The [secondary] widget is placed in the /// in the [ListTile.trailing] slot) which can be changed using [controlAffinity].
/// [ListTile.leading] slot. This cannot be changed; there is not sufficient /// The [secondary] widget is placed in the [ListTile.leading] slot.
/// space in a [ListTile]'s [ListTile.leading] slot for a [Switch].
/// ///
/// To show the [SwitchListTile] as disabled, pass null as the [onChanged] /// To show the [SwitchListTile] as disabled, pass null as the [onChanged]
/// callback. /// callback.
...@@ -273,6 +272,7 @@ class SwitchListTile extends StatelessWidget { ...@@ -273,6 +272,7 @@ class SwitchListTile extends StatelessWidget {
this.secondary, this.secondary,
this.selected = false, this.selected = false,
this.autofocus = false, this.autofocus = false,
this.controlAffinity = ListTileControlAffinity.platform,
}) : _switchListTileType = _SwitchListTileType.material, }) : _switchListTileType = _SwitchListTileType.material,
assert(value != null), assert(value != null),
assert(isThreeLine != null), assert(isThreeLine != null),
...@@ -307,6 +307,7 @@ class SwitchListTile extends StatelessWidget { ...@@ -307,6 +307,7 @@ class SwitchListTile extends StatelessWidget {
this.secondary, this.secondary,
this.selected = false, this.selected = false,
this.autofocus = false, this.autofocus = false,
this.controlAffinity = ListTileControlAffinity.platform,
}) : _switchListTileType = _SwitchListTileType.adaptive, }) : _switchListTileType = _SwitchListTileType.adaptive,
assert(value != null), assert(value != null),
assert(isThreeLine != null), assert(isThreeLine != null),
...@@ -429,6 +430,11 @@ class SwitchListTile extends StatelessWidget { ...@@ -429,6 +430,11 @@ class SwitchListTile extends StatelessWidget {
/// If adaptive, creates the switch with [Switch.adaptive]. /// If adaptive, creates the switch with [Switch.adaptive].
final _SwitchListTileType _switchListTileType; final _SwitchListTileType _switchListTileType;
/// Defines the position of control and [secondary], relative to text.
///
/// By default, the value of `controlAffinity` is [ListTileControlAffinity.platform].
final ListTileControlAffinity controlAffinity;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
Widget control; Widget control;
...@@ -462,14 +468,28 @@ class SwitchListTile extends StatelessWidget { ...@@ -462,14 +468,28 @@ class SwitchListTile extends StatelessWidget {
autofocus: autofocus, autofocus: autofocus,
); );
} }
Widget leading, trailing;
switch (controlAffinity) {
case ListTileControlAffinity.leading:
leading = control;
trailing = secondary;
break;
case ListTileControlAffinity.trailing:
case ListTileControlAffinity.platform:
leading = secondary;
trailing = control;
break;
}
return MergeSemantics( return MergeSemantics(
child: ListTileTheme.merge( child: ListTileTheme.merge(
selectedColor: activeColor ?? Theme.of(context).accentColor, selectedColor: activeColor ?? Theme.of(context).accentColor,
child: ListTile( child: ListTile(
leading: secondary, leading: leading,
title: title, title: title,
subtitle: subtitle, subtitle: subtitle,
trailing: control, trailing: trailing,
isThreeLine: isThreeLine, isThreeLine: isThreeLine,
dense: dense, dense: dense,
contentPadding: contentPadding, contentPadding: contentPadding,
......
...@@ -298,4 +298,44 @@ void main() { ...@@ -298,4 +298,44 @@ void main() {
await tester.pump(); await tester.pump();
expect(Focus.of(childKey.currentContext, nullOk: true).hasPrimaryFocus, isFalse); expect(Focus.of(childKey.currentContext, nullOk: true).hasPrimaryFocus, isFalse);
}); });
testWidgets('SwitchListTile controlAffinity test', (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp(
home: Material(
child: SwitchListTile(
value: true,
onChanged: null,
secondary: Icon(Icons.info),
title: Text('Title'),
controlAffinity: ListTileControlAffinity.leading,
),
),
));
final ListTile listTile = tester.widget(find.byType(ListTile));
// When controlAffinity is ListTileControlAffinity.leading, the position of
// Switch is at leading edge and SwitchListTile.secondary at trailing edge.
expect(listTile.leading.runtimeType, Switch);
expect(listTile.trailing.runtimeType, Icon);
});
testWidgets('SwitchListTile controlAffinity default value test', (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp(
home: Material(
child: SwitchListTile(
value: true,
onChanged: null,
secondary: Icon(Icons.info),
title: Text('Title'),
),
),
));
final ListTile listTile = tester.widget(find.byType(ListTile));
// By default, value of controlAffinity is ListTileControlAffinity.platform,
// where the position of SwitchListTile.secondary is at leading edge and Switch
// at trailing edge. This also covers test for ListTileControlAffinity.trailing.
expect(listTile.leading.runtimeType, Icon);
expect(listTile.trailing.runtimeType, Switch);
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment