added enableFeedback property to ListTile (#69088)
This commit is contained in:
parent
ef4ec09a06
commit
0afea99b26
@ -52,6 +52,7 @@ class ListTileTheme extends InheritedTheme {
|
||||
this.contentPadding,
|
||||
this.tileColor,
|
||||
this.selectedTileColor,
|
||||
this.enableFeedback,
|
||||
required Widget child,
|
||||
}) : super(key: key, child: child);
|
||||
|
||||
@ -70,6 +71,7 @@ class ListTileTheme extends InheritedTheme {
|
||||
EdgeInsetsGeometry? contentPadding,
|
||||
Color? tileColor,
|
||||
Color? selectedTileColor,
|
||||
bool? enableFeedback,
|
||||
required Widget child,
|
||||
}) {
|
||||
assert(child != null);
|
||||
@ -87,6 +89,7 @@ class ListTileTheme extends InheritedTheme {
|
||||
contentPadding: contentPadding ?? parent.contentPadding,
|
||||
tileColor: tileColor ?? parent.tileColor,
|
||||
selectedTileColor: selectedTileColor ?? parent.selectedTileColor,
|
||||
enableFeedback: enableFeedback ?? parent.enableFeedback,
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
@ -131,6 +134,11 @@ class ListTileTheme extends InheritedTheme {
|
||||
/// If [ListTile.selectedTileColor] is provided, [selectedTileColor] is ignored.
|
||||
final Color? selectedTileColor;
|
||||
|
||||
/// If specified, defines the feedback property for `ListTile`.
|
||||
///
|
||||
/// If [ListTile.enableFeedback] is provided, [enableFeedback] is ignored.
|
||||
final bool? enableFeedback;
|
||||
|
||||
/// The closest instance of this class that encloses the given context.
|
||||
///
|
||||
/// Typical usage is as follows:
|
||||
@ -155,6 +163,7 @@ class ListTileTheme extends InheritedTheme {
|
||||
contentPadding: contentPadding,
|
||||
tileColor: tileColor,
|
||||
selectedTileColor: selectedTileColor,
|
||||
enableFeedback: enableFeedback,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
@ -169,7 +178,8 @@ class ListTileTheme extends InheritedTheme {
|
||||
|| textColor != oldWidget.textColor
|
||||
|| contentPadding != oldWidget.contentPadding
|
||||
|| tileColor != oldWidget.tileColor
|
||||
|| selectedTileColor != oldWidget.selectedTileColor;
|
||||
|| selectedTileColor != oldWidget.selectedTileColor
|
||||
|| enableFeedback != oldWidget.enableFeedback;
|
||||
}
|
||||
}
|
||||
|
||||
@ -708,6 +718,7 @@ class ListTile extends StatelessWidget {
|
||||
this.autofocus = false,
|
||||
this.tileColor,
|
||||
this.selectedTileColor,
|
||||
this.enableFeedback,
|
||||
}) : assert(isThreeLine != null),
|
||||
assert(enabled != null),
|
||||
assert(selected != null),
|
||||
@ -901,6 +912,16 @@ class ListTile extends StatelessWidget {
|
||||
/// if it's not null and to [Colors.transparent] if it's null.
|
||||
final Color? selectedTileColor;
|
||||
|
||||
/// Whether detected gestures should provide acoustic and/or haptic feedback.
|
||||
///
|
||||
/// For example, on Android a tap will produce a clicking sound and a
|
||||
/// long-press will produce a short vibration, when feedback is enabled.
|
||||
///
|
||||
/// See also:
|
||||
///
|
||||
/// * [Feedback] for providing platform-specific feedback to certain actions.
|
||||
final bool? enableFeedback;
|
||||
|
||||
/// Add a one pixel border in between each tile. If color isn't specified the
|
||||
/// [ThemeData.dividerColor] of the context's [Theme] is used.
|
||||
///
|
||||
@ -1068,6 +1089,7 @@ class ListTile extends StatelessWidget {
|
||||
|
||||
const EdgeInsets _defaultContentPadding = EdgeInsets.symmetric(horizontal: 16.0);
|
||||
final TextDirection textDirection = Directionality.of(context);
|
||||
final bool resolvedEnableFeedback = enableFeedback ?? tileTheme.enableFeedback ?? true;
|
||||
final EdgeInsets resolvedContentPadding = contentPadding?.resolve(textDirection)
|
||||
?? tileTheme.contentPadding?.resolve(textDirection)
|
||||
?? _defaultContentPadding;
|
||||
@ -1090,6 +1112,7 @@ class ListTile extends StatelessWidget {
|
||||
focusColor: focusColor,
|
||||
hoverColor: hoverColor,
|
||||
autofocus: autofocus,
|
||||
enableFeedback: resolvedEnableFeedback,
|
||||
child: Semantics(
|
||||
selected: selected,
|
||||
enabled: enabled,
|
||||
|
@ -13,6 +13,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import '../rendering/mock_canvas.dart';
|
||||
import '../widgets/semantics_tester.dart';
|
||||
import 'feedback_tester.dart';
|
||||
|
||||
class TestIcon extends StatefulWidget {
|
||||
const TestIcon({ Key? key }) : super(key: key);
|
||||
@ -1712,4 +1713,125 @@ void main() {
|
||||
expect(renderBox.size.width, equals(0.0));
|
||||
expect(renderBox.size.height, equals(0.0));
|
||||
});
|
||||
|
||||
group('feedback', () {
|
||||
late FeedbackTester feedback;
|
||||
|
||||
setUp(() {
|
||||
feedback = FeedbackTester();
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
feedback.dispose();
|
||||
});
|
||||
|
||||
testWidgets('ListTile with disabled feedback', (WidgetTester tester) async {
|
||||
const bool enableFeedback = false;
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: ListTile(
|
||||
title: const Text('Title'),
|
||||
onTap: () {},
|
||||
enableFeedback: enableFeedback,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byType(ListTile));
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
expect(feedback.clickSoundCount, 0);
|
||||
expect(feedback.hapticCount, 0);
|
||||
});
|
||||
|
||||
testWidgets('ListTile with enabled feedback', (WidgetTester tester) async {
|
||||
const bool enableFeedback = true;
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: ListTile(
|
||||
title: const Text('Title'),
|
||||
onTap: () {},
|
||||
enableFeedback: enableFeedback,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byType(ListTile));
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
expect(feedback.clickSoundCount, 1);
|
||||
expect(feedback.hapticCount, 0);
|
||||
});
|
||||
|
||||
testWidgets('ListTile with enabled feedback by default', (WidgetTester tester) async {
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: ListTile(
|
||||
title: const Text('Title'),
|
||||
onTap: () {},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byType(ListTile));
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
expect(feedback.clickSoundCount, 1);
|
||||
expect(feedback.hapticCount, 0);
|
||||
});
|
||||
|
||||
testWidgets('ListTile with disabled feedback using ListTileTheme', (WidgetTester tester) async {
|
||||
const bool enableFeedbackTheme = false;
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: ListTileTheme(
|
||||
enableFeedback: enableFeedbackTheme,
|
||||
child: ListTile(
|
||||
title: const Text('Title'),
|
||||
onTap: () {},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byType(ListTile));
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
expect(feedback.clickSoundCount, 0);
|
||||
expect(feedback.hapticCount, 0);
|
||||
});
|
||||
|
||||
testWidgets('ListTile.enableFeedback overrides ListTileTheme.enableFeedback', (WidgetTester tester) async {
|
||||
const bool enableFeedbackTheme = false;
|
||||
const bool enableFeedback = true;
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: ListTileTheme(
|
||||
enableFeedback: enableFeedbackTheme,
|
||||
child: ListTile(
|
||||
enableFeedback: enableFeedback,
|
||||
title: const Text('Title'),
|
||||
onTap: () {},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byType(ListTile));
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
expect(feedback.clickSoundCount, 1);
|
||||
expect(feedback.hapticCount, 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user