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>
Katarina Sheremet <katarina@sheremet.ch>
Nicolas Schneider <nioncode+git@gmail.com>
Mikhail Zotyev <mbixjkee1392@gmail.com>
Ayush Bherwani <ayush.bherwani1998@gmail.com>
......@@ -148,6 +148,7 @@ class ListTileTheme extends InheritedTheme {
///
/// * [CheckboxListTile], which combines a [ListTile] with a [Checkbox].
/// * [RadioListTile], which combines a [ListTile] with a [Radio] button.
/// * [SwitchListTile], which combines a [ListTile] with a [Switch].
enum ListTileControlAffinity {
/// Position the control on the leading edge, and the secondary widget, if
/// any, on the trailing edge.
......
......@@ -39,9 +39,8 @@ enum _SwitchListTileType { material, adaptive }
/// 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.
/// in the [ListTile.trailing] slot). The [secondary] widget is placed in the
/// [ListTile.leading] slot. This cannot be changed; there is not sufficient
/// space in a [ListTile]'s [ListTile.leading] slot for a [Switch].
/// in the [ListTile.trailing] slot) which can be changed using [controlAffinity].
/// The [secondary] widget is placed in the [ListTile.leading] slot.
///
/// To show the [SwitchListTile] as disabled, pass null as the [onChanged]
/// callback.
......@@ -273,6 +272,7 @@ class SwitchListTile extends StatelessWidget {
this.secondary,
this.selected = false,
this.autofocus = false,
this.controlAffinity = ListTileControlAffinity.platform,
}) : _switchListTileType = _SwitchListTileType.material,
assert(value != null),
assert(isThreeLine != null),
......@@ -307,6 +307,7 @@ class SwitchListTile extends StatelessWidget {
this.secondary,
this.selected = false,
this.autofocus = false,
this.controlAffinity = ListTileControlAffinity.platform,
}) : _switchListTileType = _SwitchListTileType.adaptive,
assert(value != null),
assert(isThreeLine != null),
......@@ -429,6 +430,11 @@ class SwitchListTile extends StatelessWidget {
/// If adaptive, creates the switch with [Switch.adaptive].
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
Widget build(BuildContext context) {
Widget control;
......@@ -462,14 +468,28 @@ class SwitchListTile extends StatelessWidget {
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(
child: ListTileTheme.merge(
selectedColor: activeColor ?? Theme.of(context).accentColor,
child: ListTile(
leading: secondary,
leading: leading,
title: title,
subtitle: subtitle,
trailing: control,
trailing: trailing,
isThreeLine: isThreeLine,
dense: dense,
contentPadding: contentPadding,
......
......@@ -298,4 +298,44 @@ void main() {
await tester.pump();
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