Unverified Commit a8552ca7 authored by Justin McCandless's avatar Justin McCandless Committed by GitHub

Switch list tile adaptive (#24437)

* SwitchListTile.adaptive for wrapping an adaptive Switch

* Test SwitchListTile.adaptive same as Switch.adaptive

* Remove TODO

* Comment and switch statement cleanup
parent 26548503
...@@ -13,6 +13,8 @@ import 'theme_data.dart'; ...@@ -13,6 +13,8 @@ import 'theme_data.dart';
// void setState(VoidCallback fn) { } // void setState(VoidCallback fn) { }
// bool _lights; // bool _lights;
enum _SwitchListTileType { material, adaptive }
/// A [ListTile] with a [Switch]. In other words, a switch with a label. /// A [ListTile] with a [Switch]. In other words, a switch with a label.
/// ///
/// The entire list tile is interactive: tapping anywhere in the tile toggles /// The entire list tile is interactive: tapping anywhere in the tile toggles
...@@ -90,7 +92,39 @@ class SwitchListTile extends StatelessWidget { ...@@ -90,7 +92,39 @@ class SwitchListTile extends StatelessWidget {
this.dense, this.dense,
this.secondary, this.secondary,
this.selected = false, this.selected = false,
}) : assert(value != null), }) : _switchListTileType = _SwitchListTileType.material,
assert(value != null),
assert(isThreeLine != null),
assert(!isThreeLine || subtitle != null),
assert(selected != null),
super(key: key);
/// Creates the wrapped switch with [Switch.adaptive].
///
/// Creates a [CupertinoSwitch] if the target platform is iOS, creates a
/// material design switch otherwise.
///
/// If a [CupertinoSwitch] is created, the following parameters are
/// ignored: [activeTrackColor], [inactiveThumbColor], [inactiveTrackColor],
/// [activeThumbImage], [inactiveThumbImage], [materialTapTargetSize].
const SwitchListTile.adaptive({
Key key,
@required this.value,
@required this.onChanged,
this.activeColor,
this.activeTrackColor,
this.inactiveThumbColor,
this.inactiveTrackColor,
this.activeThumbImage,
this.inactiveThumbImage,
this.title,
this.subtitle,
this.isThreeLine = false,
this.dense,
this.secondary,
this.selected = false,
}) : _switchListTileType = _SwitchListTileType.adaptive,
assert(value != null),
assert(isThreeLine != null), assert(isThreeLine != null),
assert(!isThreeLine || subtitle != null), assert(!isThreeLine || subtitle != null),
assert(selected != null), assert(selected != null),
...@@ -134,22 +168,30 @@ class SwitchListTile extends StatelessWidget { ...@@ -134,22 +168,30 @@ class SwitchListTile extends StatelessWidget {
/// The color to use on the track when this switch is on. /// The color to use on the track when this switch is on.
/// ///
/// Defaults to [ThemeData.toggleableActiveColor] with the opacity set at 50%. /// Defaults to [ThemeData.toggleableActiveColor] with the opacity set at 50%.
///
/// Ignored if created with [SwitchListTile.adaptive].
final Color activeTrackColor; final Color activeTrackColor;
/// The color to use on the thumb when this switch is off. /// The color to use on the thumb when this switch is off.
/// ///
/// Defaults to the colors described in the Material design specification. /// Defaults to the colors described in the Material design specification.
///
/// Ignored if created with [SwitchListTile.adaptive].
final Color inactiveThumbColor; final Color inactiveThumbColor;
/// The color to use on the track when this switch is off. /// The color to use on the track when this switch is off.
/// ///
/// Defaults to the colors described in the Material design specification. /// Defaults to the colors described in the Material design specification.
///
/// Ignored if created with [SwitchListTile.adaptive].
final Color inactiveTrackColor; final Color inactiveTrackColor;
/// An image to use on the thumb of this switch when the switch is on. /// An image to use on the thumb of this switch when the switch is on.
final ImageProvider activeThumbImage; final ImageProvider activeThumbImage;
/// An image to use on the thumb of this switch when the switch is off. /// An image to use on the thumb of this switch when the switch is off.
///
/// Ignored if created with [SwitchListTile.adaptive].
final ImageProvider inactiveThumbImage; final ImageProvider inactiveThumbImage;
/// The primary content of the list tile. /// The primary content of the list tile.
...@@ -187,19 +229,40 @@ class SwitchListTile extends StatelessWidget { ...@@ -187,19 +229,40 @@ class SwitchListTile extends StatelessWidget {
/// Normally, this property is left to its default value, false. /// Normally, this property is left to its default value, false.
final bool selected; final bool selected;
/// If adaptive, creates the switch with [Switch.adaptive].
final _SwitchListTileType _switchListTileType;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final Widget control = Switch( Widget control;
value: value, switch (_switchListTileType) {
onChanged: onChanged, case _SwitchListTileType.adaptive:
activeColor: activeColor, control = Switch.adaptive(
activeThumbImage: activeThumbImage, value: value,
inactiveThumbImage: inactiveThumbImage, onChanged: onChanged,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, activeColor: activeColor,
activeTrackColor: activeTrackColor, activeThumbImage: activeThumbImage,
inactiveTrackColor: inactiveTrackColor, inactiveThumbImage: inactiveThumbImage,
inactiveThumbColor: inactiveThumbColor, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
); activeTrackColor: activeTrackColor,
inactiveTrackColor: inactiveTrackColor,
inactiveThumbColor: inactiveThumbColor,
);
break;
case _SwitchListTileType.material:
control = Switch(
value: value,
onChanged: onChanged,
activeColor: activeColor,
activeThumbImage: activeThumbImage,
inactiveThumbImage: inactiveThumbImage,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
activeTrackColor: activeTrackColor,
inactiveTrackColor: inactiveTrackColor,
inactiveThumbColor: inactiveThumbColor,
);
}
return MergeSemantics( return MergeSemantics(
child: ListTileTheme.merge( child: ListTileTheme.merge(
selectedColor: activeColor ?? Theme.of(context).accentColor, selectedColor: activeColor ?? Theme.of(context).accentColor,
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import '../rendering/mock_canvas.dart'; import '../rendering/mock_canvas.dart';
...@@ -58,4 +59,45 @@ void main() { ...@@ -58,4 +59,45 @@ void main() {
..circle(color: Colors.red[500]) ..circle(color: Colors.red[500])
); );
}); });
testWidgets('SwitchListTile.adaptive delegates to', (WidgetTester tester) async {
bool value = false;
Widget buildFrame(TargetPlatform platform) {
return MaterialApp(
theme: ThemeData(platform: platform),
home: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Material(
child: Center(
child: SwitchListTile.adaptive(
value: value,
onChanged: (bool newValue) {
setState(() {
value = newValue;
});
},
),
),
);
},
),
);
}
await tester.pumpWidget(buildFrame(TargetPlatform.iOS));
expect(find.byType(CupertinoSwitch), findsOneWidget);
expect(value, isFalse);
await tester.tap(find.byType(SwitchListTile));
expect(value, isTrue);
await tester.pumpWidget(buildFrame(TargetPlatform.android));
await tester.pumpAndSettle(); // Finish the theme change animation.
expect(find.byType(CupertinoSwitch), findsNothing);
expect(value, isTrue);
await tester.tap(find.byType(SwitchListTile));
expect(value, isFalse);
});
} }
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