Skip to content

Commit 7dbd586

Browse files
authored
Reland "ListTile Material Ripple and Shape Patch (flutter#74373)" (flutter#76892)
This reverts commit f8cd24d in an attempt to re-land it. There are no changes in this PR from flutter#74373, since it only failed Google internal tests, and we think that the solution involves updating those tests instead of changing this code.
1 parent c9ccb17 commit 7dbd586

File tree

8 files changed

+213
-105
lines changed

8 files changed

+213
-105
lines changed

packages/flutter/lib/src/material/ink_decoration.dart

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,13 @@ class Ink extends StatefulWidget {
215215
/// any [padding].
216216
final double? height;
217217

218-
EdgeInsetsGeometry? get _paddingIncludingDecoration {
218+
EdgeInsetsGeometry get _paddingIncludingDecoration {
219219
if (decoration == null || decoration!.padding == null)
220-
return padding;
221-
final EdgeInsetsGeometry? decorationPadding = decoration!.padding;
220+
return padding ?? EdgeInsets.zero;
221+
final EdgeInsetsGeometry decorationPadding = decoration!.padding!;
222222
if (padding == null)
223223
return decorationPadding;
224-
return padding!.add(decorationPadding!);
224+
return padding!.add(decorationPadding);
225225
}
226226

227227
@override
@@ -236,6 +236,7 @@ class Ink extends StatefulWidget {
236236
}
237237

238238
class _InkState extends State<Ink> {
239+
final GlobalKey _boxKey = GlobalKey();
239240
InkDecoration? _ink;
240241

241242
void _handleRemoved() {
@@ -249,31 +250,31 @@ class _InkState extends State<Ink> {
249250
super.deactivate();
250251
}
251252

252-
Widget _build(BuildContext context, BoxConstraints constraints) {
253+
Widget _build(BuildContext context) {
254+
// By creating the InkDecoration from within a Builder widget, we can
255+
// use the RenderBox of the Padding widget.
253256
if (_ink == null) {
254257
_ink = InkDecoration(
255258
decoration: widget.decoration,
256259
configuration: createLocalImageConfiguration(context),
257260
controller: Material.of(context)!,
258-
referenceBox: context.findRenderObject()! as RenderBox,
261+
referenceBox: _boxKey.currentContext!.findRenderObject()! as RenderBox,
259262
onRemoved: _handleRemoved,
260263
);
261264
} else {
262265
_ink!.decoration = widget.decoration;
263266
_ink!.configuration = createLocalImageConfiguration(context);
264267
}
265-
Widget? current = widget.child;
266-
final EdgeInsetsGeometry? effectivePadding = widget._paddingIncludingDecoration;
267-
if (effectivePadding != null)
268-
current = Padding(padding: effectivePadding, child: current);
269-
return current ?? Container();
268+
return widget.child ?? Container();
270269
}
271270

272271
@override
273272
Widget build(BuildContext context) {
274273
assert(debugCheckHasMaterial(context));
275-
Widget result = LayoutBuilder(
276-
builder: _build,
274+
Widget result = Padding(
275+
key: _boxKey,
276+
padding: widget._paddingIncludingDecoration,
277+
child: Builder(builder: _build),
277278
);
278279
if (widget.width != null || widget.height != null) {
279280
result = SizedBox(

packages/flutter/lib/src/material/list_tile.dart

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import 'colors.dart';
1111
import 'constants.dart';
1212
import 'debug.dart';
1313
import 'divider.dart';
14+
import 'ink_decoration.dart';
1415
import 'ink_well.dart';
1516
import 'material_state.dart';
1617
import 'theme.dart';
@@ -108,7 +109,7 @@ class ListTileTheme extends InheritedTheme {
108109
final bool dense;
109110

110111
/// {@template flutter.material.ListTileTheme.shape}
111-
/// If specified, [shape] defines the shape of the [ListTile]'s [InkWell] border.
112+
/// If specified, [shape] defines the [ListTile]'s shape.
112113
/// {@endtemplate}
113114
final ShapeBorder? shape;
114115

@@ -837,13 +838,12 @@ class ListTile extends StatelessWidget {
837838
/// widgets within a [Theme].
838839
final VisualDensity? visualDensity;
839840

840-
/// The shape of the tile's [InkWell].
841+
/// The tile's shape.
841842
///
842-
/// Defines the tile's [InkWell.customBorder].
843+
/// Defines the tile's [InkWell.customBorder] and [Ink.decoration] shape.
843844
///
844-
/// If this property is null then [CardTheme.shape] of [ThemeData.cardTheme]
845-
/// is used. If that's null then the shape will be a [RoundedRectangleBorder]
846-
/// with a circular corner radius of 4.0.
845+
/// If this property is null then [ListTileTheme.shape] is used.
846+
/// If that's null then a rectangular [Border] will be used.
847847
final ShapeBorder? shape;
848848

849849
/// The tile's internal padding.
@@ -1185,8 +1185,11 @@ class ListTile extends StatelessWidget {
11851185
child: Semantics(
11861186
selected: selected,
11871187
enabled: enabled,
1188-
child: ColoredBox(
1189-
color: _tileBackgroundColor(tileTheme),
1188+
child: Ink(
1189+
decoration: ShapeDecoration(
1190+
shape: shape ?? tileTheme.shape ?? const Border(),
1191+
color: _tileBackgroundColor(tileTheme),
1192+
),
11901193
child: SafeArea(
11911194
top: false,
11921195
bottom: false,

packages/flutter/lib/src/rendering/sliver_multi_box_adaptor.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,13 @@ abstract class RenderSliverMultiBoxAdaptor extends RenderSliver
577577

578578
@override
579579
void applyPaintTransform(RenderBox child, Matrix4 transform) {
580-
if (_keepAliveBucket.containsKey(indexOf(child))) {
580+
final SliverMultiBoxAdaptorParentData childParentData = child.parentData! as SliverMultiBoxAdaptorParentData;
581+
if (childParentData.index == null) {
582+
// If the child has no index, such as with the prototype of a
583+
// SliverPrototypeExtentList, then it is not visible, so we give it a
584+
// zero transform to prevent it from painting.
585+
transform.setZero();
586+
} else if (_keepAliveBucket.containsKey(childParentData.index)) {
581587
// It is possible that widgets under kept alive children want to paint
582588
// themselves. For example, the Material widget tries to paint all
583589
// InkFeatures under its subtree as long as they are not disposed. In

packages/flutter/test/material/checkbox_list_tile_test.dart

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ void main() {
134134
)
135135
);
136136

137-
final Rect paddingRect = tester.getRect(find.byType(Padding));
137+
final Rect paddingRect = tester.getRect(find.byType(SafeArea));
138138
final Rect checkboxRect = tester.getRect(find.byType(Checkbox));
139139
final Rect titleRect = tester.getRect(find.text('Title'));
140140

@@ -246,43 +246,41 @@ void main() {
246246
});
247247

248248
testWidgets('CheckboxListTile respects tileColor', (WidgetTester tester) async {
249-
const Color tileColor = Colors.black;
249+
final Color tileColor = Colors.red.shade500;
250250

251251
await tester.pumpWidget(
252252
wrap(
253-
child: const Center(
253+
child: Center(
254254
child: CheckboxListTile(
255255
value: false,
256256
onChanged: null,
257-
title: Text('Title'),
257+
title: const Text('Title'),
258258
tileColor: tileColor,
259259
),
260260
),
261261
),
262262
);
263263

264-
final ColoredBox coloredBox = tester.firstWidget(find.byType(ColoredBox));
265-
expect(coloredBox.color, equals(tileColor));
264+
expect(find.byType(Material), paints..path(color: tileColor));
266265
});
267266

268267
testWidgets('CheckboxListTile respects selectedTileColor', (WidgetTester tester) async {
269-
const Color selectedTileColor = Colors.black;
268+
final Color selectedTileColor = Colors.green.shade500;
270269

271270
await tester.pumpWidget(
272271
wrap(
273-
child: const Center(
272+
child: Center(
274273
child: CheckboxListTile(
275274
value: false,
276275
onChanged: null,
277-
title: Text('Title'),
276+
title: const Text('Title'),
278277
selected: true,
279278
selectedTileColor: selectedTileColor,
280279
),
281280
),
282281
),
283282
);
284283

285-
final ColoredBox coloredBox = tester.firstWidget(find.byType(ColoredBox));
286-
expect(coloredBox.color, equals(selectedTileColor));
284+
expect(find.byType(Material), paints..path(color: selectedTileColor));
287285
});
288286
}

0 commit comments

Comments
 (0)