Skip to content

Commit ad50772

Browse files
authored
fix Applying decoration for a table row widget will cause render exception (flutter#34285)
1 parent c40c687 commit ad50772

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,8 @@ class RenderTable extends RenderBox {
518518
/// the table, unlike decorations for individual cells, which might not fill
519519
/// either.
520520
List<Decoration> get rowDecorations => List<Decoration>.unmodifiable(_rowDecorations ?? const <Decoration>[]);
521+
// _rowDecorations and _rowDecorationPainters need to be in sync. They have to
522+
// either both be null or have same length.
521523
List<Decoration> _rowDecorations;
522524
List<BoxPainter> _rowDecorationPainters;
523525
set rowDecorations(List<Decoration> value) {
@@ -703,7 +705,7 @@ class RenderTable extends RenderBox {
703705
if (_rowDecorationPainters != null) {
704706
for (BoxPainter painter in _rowDecorationPainters)
705707
painter?.dispose();
706-
_rowDecorationPainters = null;
708+
_rowDecorationPainters = List<BoxPainter>(_rowDecorations.length);
707709
}
708710
for (RenderBox child in _children)
709711
child?.detach();
@@ -1137,6 +1139,7 @@ class RenderTable extends RenderBox {
11371139
}
11381140
assert(_rowTops.length == rows + 1);
11391141
if (_rowDecorations != null) {
1142+
assert(_rowDecorations.length == _rowDecorationPainters.length);
11401143
final Canvas canvas = context.canvas;
11411144
for (int y = 0; y < rows; y += 1) {
11421145
if (_rowDecorations.length <= y)

packages/flutter/test/widgets/table_test.dart

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import 'package:flutter_test/flutter_test.dart';
66
import 'package:flutter/rendering.dart';
77
import 'package:flutter/widgets.dart';
8+
import 'package:flutter/material.dart';
89

910
class TestStatefulWidget extends StatefulWidget {
1011
const TestStatefulWidget({ Key key }) : super(key: key);
@@ -67,6 +68,41 @@ void main() {
6768
await run(TextDirection.rtl);
6869
});
6970

71+
testWidgets('Table widget can be detached and re-attached', (WidgetTester tester) async {
72+
final Widget table = Table(
73+
key: GlobalKey(),
74+
children: const <TableRow>[
75+
TableRow(
76+
decoration: BoxDecoration(
77+
color: Colors.yellow
78+
),
79+
children: <Widget>[Placeholder()],
80+
),
81+
],
82+
);
83+
await tester.pumpWidget(
84+
Directionality(
85+
textDirection: TextDirection.ltr,
86+
child: Center(
87+
child: table,
88+
),
89+
),
90+
);
91+
// Move table to a different location to simulate detaching and re-attaching effect.
92+
await tester.pumpWidget(
93+
Directionality(
94+
textDirection: TextDirection.ltr,
95+
child: Center(
96+
child: Center(
97+
child: table
98+
),
99+
),
100+
),
101+
);
102+
103+
expect(tester.takeException(), isNull);
104+
});
105+
70106
testWidgets('Table widget - column offset (LTR)', (WidgetTester tester) async {
71107
await tester.pumpWidget(
72108
Directionality(

0 commit comments

Comments
 (0)