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.contentPadding,
|
||||||
this.tileColor,
|
this.tileColor,
|
||||||
this.selectedTileColor,
|
this.selectedTileColor,
|
||||||
|
this.enableFeedback,
|
||||||
required Widget child,
|
required Widget child,
|
||||||
}) : super(key: key, child: child);
|
}) : super(key: key, child: child);
|
||||||
|
|
||||||
@ -70,6 +71,7 @@ class ListTileTheme extends InheritedTheme {
|
|||||||
EdgeInsetsGeometry? contentPadding,
|
EdgeInsetsGeometry? contentPadding,
|
||||||
Color? tileColor,
|
Color? tileColor,
|
||||||
Color? selectedTileColor,
|
Color? selectedTileColor,
|
||||||
|
bool? enableFeedback,
|
||||||
required Widget child,
|
required Widget child,
|
||||||
}) {
|
}) {
|
||||||
assert(child != null);
|
assert(child != null);
|
||||||
@ -87,6 +89,7 @@ class ListTileTheme extends InheritedTheme {
|
|||||||
contentPadding: contentPadding ?? parent.contentPadding,
|
contentPadding: contentPadding ?? parent.contentPadding,
|
||||||
tileColor: tileColor ?? parent.tileColor,
|
tileColor: tileColor ?? parent.tileColor,
|
||||||
selectedTileColor: selectedTileColor ?? parent.selectedTileColor,
|
selectedTileColor: selectedTileColor ?? parent.selectedTileColor,
|
||||||
|
enableFeedback: enableFeedback ?? parent.enableFeedback,
|
||||||
child: child,
|
child: child,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -131,6 +134,11 @@ class ListTileTheme extends InheritedTheme {
|
|||||||
/// If [ListTile.selectedTileColor] is provided, [selectedTileColor] is ignored.
|
/// If [ListTile.selectedTileColor] is provided, [selectedTileColor] is ignored.
|
||||||
final Color? selectedTileColor;
|
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.
|
/// The closest instance of this class that encloses the given context.
|
||||||
///
|
///
|
||||||
/// Typical usage is as follows:
|
/// Typical usage is as follows:
|
||||||
@ -155,6 +163,7 @@ class ListTileTheme extends InheritedTheme {
|
|||||||
contentPadding: contentPadding,
|
contentPadding: contentPadding,
|
||||||
tileColor: tileColor,
|
tileColor: tileColor,
|
||||||
selectedTileColor: selectedTileColor,
|
selectedTileColor: selectedTileColor,
|
||||||
|
enableFeedback: enableFeedback,
|
||||||
child: child,
|
child: child,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -169,7 +178,8 @@ class ListTileTheme extends InheritedTheme {
|
|||||||
|| textColor != oldWidget.textColor
|
|| textColor != oldWidget.textColor
|
||||||
|| contentPadding != oldWidget.contentPadding
|
|| contentPadding != oldWidget.contentPadding
|
||||||
|| tileColor != oldWidget.tileColor
|
|| tileColor != oldWidget.tileColor
|
||||||
|| selectedTileColor != oldWidget.selectedTileColor;
|
|| selectedTileColor != oldWidget.selectedTileColor
|
||||||
|
|| enableFeedback != oldWidget.enableFeedback;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -708,6 +718,7 @@ class ListTile extends StatelessWidget {
|
|||||||
this.autofocus = false,
|
this.autofocus = false,
|
||||||
this.tileColor,
|
this.tileColor,
|
||||||
this.selectedTileColor,
|
this.selectedTileColor,
|
||||||
|
this.enableFeedback,
|
||||||
}) : assert(isThreeLine != null),
|
}) : assert(isThreeLine != null),
|
||||||
assert(enabled != null),
|
assert(enabled != null),
|
||||||
assert(selected != 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.
|
/// if it's not null and to [Colors.transparent] if it's null.
|
||||||
final Color? selectedTileColor;
|
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
|
/// Add a one pixel border in between each tile. If color isn't specified the
|
||||||
/// [ThemeData.dividerColor] of the context's [Theme] is used.
|
/// [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);
|
const EdgeInsets _defaultContentPadding = EdgeInsets.symmetric(horizontal: 16.0);
|
||||||
final TextDirection textDirection = Directionality.of(context);
|
final TextDirection textDirection = Directionality.of(context);
|
||||||
|
final bool resolvedEnableFeedback = enableFeedback ?? tileTheme.enableFeedback ?? true;
|
||||||
final EdgeInsets resolvedContentPadding = contentPadding?.resolve(textDirection)
|
final EdgeInsets resolvedContentPadding = contentPadding?.resolve(textDirection)
|
||||||
?? tileTheme.contentPadding?.resolve(textDirection)
|
?? tileTheme.contentPadding?.resolve(textDirection)
|
||||||
?? _defaultContentPadding;
|
?? _defaultContentPadding;
|
||||||
@ -1090,6 +1112,7 @@ class ListTile extends StatelessWidget {
|
|||||||
focusColor: focusColor,
|
focusColor: focusColor,
|
||||||
hoverColor: hoverColor,
|
hoverColor: hoverColor,
|
||||||
autofocus: autofocus,
|
autofocus: autofocus,
|
||||||
|
enableFeedback: resolvedEnableFeedback,
|
||||||
child: Semantics(
|
child: Semantics(
|
||||||
selected: selected,
|
selected: selected,
|
||||||
enabled: enabled,
|
enabled: enabled,
|
||||||
|
@ -13,6 +13,7 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
|
|
||||||
import '../rendering/mock_canvas.dart';
|
import '../rendering/mock_canvas.dart';
|
||||||
import '../widgets/semantics_tester.dart';
|
import '../widgets/semantics_tester.dart';
|
||||||
|
import 'feedback_tester.dart';
|
||||||
|
|
||||||
class TestIcon extends StatefulWidget {
|
class TestIcon extends StatefulWidget {
|
||||||
const TestIcon({ Key? key }) : super(key: key);
|
const TestIcon({ Key? key }) : super(key: key);
|
||||||
@ -1712,4 +1713,125 @@ void main() {
|
|||||||
expect(renderBox.size.width, equals(0.0));
|
expect(renderBox.size.width, equals(0.0));
|
||||||
expect(renderBox.size.height, 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