Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
f4603f76
Commit
f4603f76
authored
Mar 29, 2016
by
Ian Hickson
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2961 from Hixie/table
Table widget
parents
a5ee6e11
baf06515
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
748 additions
and
83 deletions
+748
-83
paragraph.dart
packages/flutter/lib/src/rendering/paragraph.dart
+1
-1
table.dart
packages/flutter/lib/src/rendering/table.dart
+126
-61
basic.dart
packages/flutter/lib/src/widgets/basic.dart
+4
-4
framework.dart
packages/flutter/lib/src/widgets/framework.dart
+25
-17
table.dart
packages/flutter/lib/src/widgets/table.dart
+231
-0
widgets.dart
packages/flutter/lib/widgets.dart
+1
-0
table_test.dart
packages/flutter/test/rendering/table_test.dart
+16
-0
table_test.dart
packages/flutter/test/widget/table_test.dart
+344
-0
No files found.
packages/flutter/lib/src/rendering/paragraph.dart
View file @
f4603f76
...
@@ -131,7 +131,7 @@ class RenderParagraph extends RenderBox {
...
@@ -131,7 +131,7 @@ class RenderParagraph extends RenderBox {
@override
@override
String
debugDescribeChildren
(
String
prefix
)
{
String
debugDescribeChildren
(
String
prefix
)
{
return
'
$prefix
\
u2558
\
u2550
\
u2566
\
u2550
\
u2550 text
\
u2550
\
u2550
\
u2550
\n
'
return
'
$prefix
\
u2558
\
u2550
\
u2566
\
u2550
\
u2550 text
\
u2550
\
u2550
\
u2550
\n
'
'
${text.toString("$prefix \u2551 ")}
\n
'
'
${text.toString("$prefix \u2551 ")}
'
// TextSpan includes a newline
'
$prefix
\
u255A
\
u2550
\
u2550
\
u2550
\
u2550
\
u2550
\
u2550
\
u2550
\
u2550
\
u2550
\
u2550
\
u2550
\n
'
'
$prefix
\
u255A
\
u2550
\
u2550
\
u2550
\
u2550
\
u2550
\
u2550
\
u2550
\
u2550
\
u2550
\
u2550
\
u2550
\n
'
'
$prefix
\n
'
;
'
$prefix
\n
'
;
}
}
...
...
packages/flutter/lib/src/rendering/table.dart
View file @
f4603f76
...
@@ -12,6 +12,12 @@ import 'object.dart';
...
@@ -12,6 +12,12 @@ import 'object.dart';
class
TableCellParentData
extends
BoxParentData
{
class
TableCellParentData
extends
BoxParentData
{
TableCellVerticalAlignment
verticalAlignment
;
TableCellVerticalAlignment
verticalAlignment
;
/// The column that the child was in the last time it was laid out.
int
x
;
/// The row that the child was in the last time it was laid out.
int
y
;
@override
@override
String
toString
()
=>
'
${super.toString()}
;
$verticalAlignment
'
;
String
toString
()
=>
'
${super.toString()}
;
$verticalAlignment
'
;
}
}
...
@@ -383,6 +389,15 @@ class RenderTable extends RenderBox {
...
@@ -383,6 +389,15 @@ class RenderTable extends RenderBox {
for
(
int
x
=
0
;
x
<
columnsToCopy
;
x
+=
1
)
for
(
int
x
=
0
;
x
<
columnsToCopy
;
x
+=
1
)
_children
[
x
+
y
*
columns
]
=
oldChildren
[
x
+
y
*
oldColumns
];
_children
[
x
+
y
*
columns
]
=
oldChildren
[
x
+
y
*
oldColumns
];
}
}
if
(
oldColumns
>
columns
)
{
for
(
int
y
=
0
;
y
<
rows
;
y
+=
1
)
{
for
(
int
x
=
columns
;
x
<
oldColumns
;
x
+=
1
)
{
int
xy
=
x
+
y
*
oldColumns
;
if
(
oldChildren
[
xy
]
!=
null
)
dropChild
(
oldChildren
[
xy
]);
}
}
}
markNeedsLayout
();
markNeedsLayout
();
}
}
...
@@ -393,14 +408,21 @@ class RenderTable extends RenderBox {
...
@@ -393,14 +408,21 @@ class RenderTable extends RenderBox {
assert
(
value
>=
0
);
assert
(
value
>=
0
);
if
(
value
==
rows
)
if
(
value
==
rows
)
return
;
return
;
if
(
_rows
>
value
)
{
for
(
int
xy
=
columns
*
value
;
xy
<
_children
.
length
;
xy
+=
1
)
{
if
(
_children
[
xy
]
!=
null
)
dropChild
(
_children
[
xy
]);
}
}
_rows
=
value
;
_rows
=
value
;
_children
.
length
=
columns
*
rows
;
_children
.
length
=
columns
*
rows
;
markNeedsLayout
();
markNeedsLayout
();
}
}
Map
<
int
,
TableColumnWidth
>
_columnWidths
;
Map
<
int
,
TableColumnWidth
>
_columnWidths
;
void
setColumnWidths
(
Map
<
int
,
TableColumnWidth
>
value
)
{
Map
<
int
,
TableColumnWidth
>
get
columnWidths
=>
new
Map
<
int
,
TableColumnWidth
>.
unmodifiable
(
_columnWidths
);
assert
(
value
!=
null
);
void
set
columnWidths
(
Map
<
int
,
TableColumnWidth
>
value
)
{
value
??=
new
HashMap
<
int
,
TableColumnWidth
>();
if
(
_columnWidths
==
value
)
if
(
_columnWidths
==
value
)
return
;
return
;
_columnWidths
=
value
;
_columnWidths
=
value
;
...
@@ -460,16 +482,19 @@ class RenderTable extends RenderBox {
...
@@ -460,16 +482,19 @@ class RenderTable extends RenderBox {
void
setFlatChildren
(
int
columns
,
List
<
RenderBox
>
cells
)
{
void
setFlatChildren
(
int
columns
,
List
<
RenderBox
>
cells
)
{
if
(
cells
==
_children
&&
columns
==
_columns
)
if
(
cells
==
_children
&&
columns
==
_columns
)
return
;
return
;
assert
(
columns
>=
0
);
// consider the case of a newly empty table
if
(
columns
==
0
||
cells
.
length
==
0
)
{
assert
(
cells
==
null
||
cells
.
length
==
0
);
_columns
=
columns
;
if
(
_children
.
length
==
0
)
{
assert
(
_rows
==
0
);
return
;
}
for
(
RenderBox
oldChild
in
cells
)
{
for
(
RenderBox
oldChild
in
cells
)
{
if
(
oldChild
!=
null
)
if
(
oldChild
!=
null
)
dropChild
(
oldChild
);
dropChild
(
oldChild
);
}
}
assert
(
columns
>=
0
);
if
(
columns
==
0
)
{
assert
(
cells
==
null
||
cells
.
length
==
0
);
if
(
_children
.
length
==
0
)
return
;
_columns
=
0
;
_rows
=
0
;
_rows
=
0
;
_children
.
clear
();
_children
.
clear
();
markNeedsLayout
();
markNeedsLayout
();
...
@@ -477,34 +502,55 @@ class RenderTable extends RenderBox {
...
@@ -477,34 +502,55 @@ class RenderTable extends RenderBox {
}
}
assert
(
cells
!=
null
);
assert
(
cells
!=
null
);
assert
(
cells
.
length
%
columns
==
0
);
assert
(
cells
.
length
%
columns
==
0
);
_columns
=
columns
;
// remove cells that are moving away
_rows
=
cells
.
length
%
columns
;
for
(
int
y
=
0
;
y
<
_columns
;
y
+=
1
)
{
_children
=
cells
;
for
(
int
x
=
0
;
x
<
_rows
;
x
+=
1
)
{
for
(
RenderBox
cell
in
cells
)
{
int
xyOld
=
x
+
y
*
_columns
;
if
(
cell
!=
null
)
int
xyNew
=
x
+
y
*
columns
;
adoptChild
(
cell
);
if
(
_children
[
xyOld
]
!=
null
&&
(
x
>=
columns
||
xyNew
>=
cells
.
length
||
_children
[
xyOld
]
!=
cells
[
xyNew
]))
dropChild
(
_children
[
xyOld
]);
}
}
// adopt cells that are arriving
int
y
=
0
;
while
(
y
*
columns
<
cells
.
length
)
{
for
(
int
x
=
0
;
x
<
columns
;
x
+=
1
)
{
int
xyNew
=
x
+
y
*
columns
;
int
xyOld
=
x
+
y
*
_columns
;
if
(
cells
[
xyNew
]
!=
null
&&
(
x
>=
_columns
||
y
>=
_rows
||
_children
[
xyOld
]
!=
cells
[
xyNew
]))
adoptChild
(
cells
[
xyNew
]);
}
y
+=
1
;
}
}
// update our internal values
_columns
=
columns
;
_rows
=
cells
.
length
~/
columns
;
_children
=
cells
.
toList
();
assert
(
_children
.
length
==
rows
*
columns
);
markNeedsLayout
();
markNeedsLayout
();
}
}
void
setChildren
(
List
<
List
<
RenderBox
>>
cells
)
{
void
setChildren
(
List
<
List
<
RenderBox
>>
cells
)
{
// TODO(ianh): Make this smarter, like setFlatChildren
if
(
cells
==
null
)
{
if
(
cells
==
null
)
{
setFlatChildren
(
0
,
null
);
setFlatChildren
(
0
,
null
);
return
;
return
;
}
}
for
(
RenderBox
oldChild
in
cells
)
{
for
(
RenderBox
oldChild
in
_children
)
{
if
(
oldChild
!=
null
)
if
(
oldChild
!=
null
)
dropChild
(
oldChild
);
dropChild
(
oldChild
);
}
}
_children
.
clear
();
_columns
=
cells
.
length
>
0
?
cells
.
first
.
length
:
0
;
_columns
=
cells
.
length
>
0
?
cells
.
first
.
length
:
0
;
_rows
=
0
;
_rows
=
0
;
_children
.
clear
();
for
(
List
<
RenderBox
>
row
in
cells
)
for
(
List
<
RenderBox
>
row
in
cells
)
addRow
(
row
);
addRow
(
row
);
assert
(
_children
.
length
==
rows
*
columns
);
}
}
void
addRow
(
List
<
RenderBox
>
cells
)
{
void
addRow
(
List
<
RenderBox
>
cells
)
{
assert
(
cells
.
length
==
columns
);
assert
(
cells
.
length
==
columns
);
assert
(
_children
.
length
==
rows
*
columns
);
_rows
+=
1
;
_rows
+=
1
;
_children
.
addAll
(
cells
);
_children
.
addAll
(
cells
);
for
(
RenderBox
cell
in
cells
)
{
for
(
RenderBox
cell
in
cells
)
{
...
@@ -518,6 +564,7 @@ class RenderTable extends RenderBox {
...
@@ -518,6 +564,7 @@ class RenderTable extends RenderBox {
assert
(
x
!=
null
);
assert
(
x
!=
null
);
assert
(
y
!=
null
);
assert
(
y
!=
null
);
assert
(
x
>=
0
&&
x
<
columns
&&
y
>=
0
&&
y
<
rows
);
assert
(
x
>=
0
&&
x
<
columns
&&
y
>=
0
&&
y
<
rows
);
assert
(
_children
.
length
==
rows
*
columns
);
final
int
xy
=
x
+
y
*
columns
;
final
int
xy
=
x
+
y
*
columns
;
RenderBox
oldChild
=
_children
[
xy
];
RenderBox
oldChild
=
_children
[
xy
];
if
(
oldChild
!=
null
)
if
(
oldChild
!=
null
)
...
@@ -543,6 +590,7 @@ class RenderTable extends RenderBox {
...
@@ -543,6 +590,7 @@ class RenderTable extends RenderBox {
@override
@override
void
visitChildren
(
RenderObjectVisitor
visitor
)
{
void
visitChildren
(
RenderObjectVisitor
visitor
)
{
assert
(
_children
.
length
==
rows
*
columns
);
for
(
RenderBox
child
in
_children
)
{
for
(
RenderBox
child
in
_children
)
{
if
(
child
!=
null
)
if
(
child
!=
null
)
visitor
(
child
);
visitor
(
child
);
...
@@ -552,6 +600,7 @@ class RenderTable extends RenderBox {
...
@@ -552,6 +600,7 @@ class RenderTable extends RenderBox {
@override
@override
double
getMinIntrinsicWidth
(
BoxConstraints
constraints
)
{
double
getMinIntrinsicWidth
(
BoxConstraints
constraints
)
{
assert
(
constraints
.
debugAssertIsNormalized
);
assert
(
constraints
.
debugAssertIsNormalized
);
assert
(
_children
.
length
==
rows
*
columns
);
double
totalMinWidth
=
0.0
;
double
totalMinWidth
=
0.0
;
for
(
int
x
=
0
;
x
<
columns
;
x
+=
1
)
{
for
(
int
x
=
0
;
x
<
columns
;
x
+=
1
)
{
TableColumnWidth
columnWidth
=
_columnWidths
[
x
]
??
defaultColumnWidth
;
TableColumnWidth
columnWidth
=
_columnWidths
[
x
]
??
defaultColumnWidth
;
...
@@ -564,6 +613,7 @@ class RenderTable extends RenderBox {
...
@@ -564,6 +613,7 @@ class RenderTable extends RenderBox {
@override
@override
double
getMaxIntrinsicWidth
(
BoxConstraints
constraints
)
{
double
getMaxIntrinsicWidth
(
BoxConstraints
constraints
)
{
assert
(
constraints
.
debugAssertIsNormalized
);
assert
(
constraints
.
debugAssertIsNormalized
);
assert
(
_children
.
length
==
rows
*
columns
);
double
totalMaxWidth
=
0.0
;
double
totalMaxWidth
=
0.0
;
for
(
int
x
=
0
;
x
<
columns
;
x
+=
1
)
{
for
(
int
x
=
0
;
x
<
columns
;
x
+=
1
)
{
TableColumnWidth
columnWidth
=
_columnWidths
[
x
]
??
defaultColumnWidth
;
TableColumnWidth
columnWidth
=
_columnWidths
[
x
]
??
defaultColumnWidth
;
...
@@ -578,6 +628,7 @@ class RenderTable extends RenderBox {
...
@@ -578,6 +628,7 @@ class RenderTable extends RenderBox {
// winner of the 2016 world's most expensive intrinsic dimension function award
// winner of the 2016 world's most expensive intrinsic dimension function award
// honorable mention, most likely to improve if taught about memoization award
// honorable mention, most likely to improve if taught about memoization award
assert
(
constraints
.
debugAssertIsNormalized
);
assert
(
constraints
.
debugAssertIsNormalized
);
assert
(
_children
.
length
==
rows
*
columns
);
final
List
<
double
>
widths
=
computeColumnWidths
(
constraints
);
final
List
<
double
>
widths
=
computeColumnWidths
(
constraints
);
double
rowTop
=
0.0
;
double
rowTop
=
0.0
;
for
(
int
y
=
0
;
y
<
rows
;
y
+=
1
)
{
for
(
int
y
=
0
;
y
<
rows
;
y
+=
1
)
{
...
@@ -626,6 +677,7 @@ class RenderTable extends RenderBox {
...
@@ -626,6 +677,7 @@ class RenderTable extends RenderBox {
}
}
List
<
double
>
computeColumnWidths
(
BoxConstraints
constraints
)
{
List
<
double
>
computeColumnWidths
(
BoxConstraints
constraints
)
{
assert
(
_children
.
length
==
rows
*
columns
);
final
List
<
double
>
widths
=
new
List
<
double
>(
columns
);
final
List
<
double
>
widths
=
new
List
<
double
>(
columns
);
final
List
<
double
>
flexes
=
new
List
<
double
>(
columns
);
final
List
<
double
>
flexes
=
new
List
<
double
>(
columns
);
double
totalMinWidth
=
0.0
;
double
totalMinWidth
=
0.0
;
...
@@ -677,7 +729,10 @@ class RenderTable extends RenderBox {
...
@@ -677,7 +729,10 @@ class RenderTable extends RenderBox {
@override
@override
void
performLayout
()
{
void
performLayout
()
{
assert
(
_children
.
length
==
rows
*
columns
);
if
(
rows
*
columns
==
0
)
{
if
(
rows
*
columns
==
0
)
{
// TODO(ianh): if columns is zero, this should be zero width
// TODO(ianh): if columns is not zero, this should be based on the column width specifications
size
=
constraints
.
constrain
(
const
Size
(
double
.
INFINITY
,
0.0
));
size
=
constraints
.
constrain
(
const
Size
(
double
.
INFINITY
,
0.0
));
return
;
return
;
}
}
...
@@ -704,6 +759,8 @@ class RenderTable extends RenderBox {
...
@@ -704,6 +759,8 @@ class RenderTable extends RenderBox {
RenderBox
child
=
_children
[
xy
];
RenderBox
child
=
_children
[
xy
];
if
(
child
!=
null
)
{
if
(
child
!=
null
)
{
TableCellParentData
childParentData
=
child
.
parentData
;
TableCellParentData
childParentData
=
child
.
parentData
;
childParentData
.
x
=
x
;
childParentData
.
y
=
y
;
switch
(
childParentData
.
verticalAlignment
??
defaultVerticalAlignment
)
{
switch
(
childParentData
.
verticalAlignment
??
defaultVerticalAlignment
)
{
case
TableCellVerticalAlignment
.
baseline
:
case
TableCellVerticalAlignment
.
baseline
:
assert
(
textBaseline
!=
null
);
assert
(
textBaseline
!=
null
);
...
@@ -769,6 +826,7 @@ class RenderTable extends RenderBox {
...
@@ -769,6 +826,7 @@ class RenderTable extends RenderBox {
@override
@override
bool
hitTestChildren
(
HitTestResult
result
,
{
Point
position
})
{
bool
hitTestChildren
(
HitTestResult
result
,
{
Point
position
})
{
assert
(
_children
.
length
==
rows
*
columns
);
for
(
int
index
=
_children
.
length
-
1
;
index
>=
0
;
index
-=
1
)
{
for
(
int
index
=
_children
.
length
-
1
;
index
>=
0
;
index
-=
1
)
{
RenderBox
child
=
_children
[
index
];
RenderBox
child
=
_children
[
index
];
if
(
child
!=
null
)
{
if
(
child
!=
null
)
{
...
@@ -784,6 +842,7 @@ class RenderTable extends RenderBox {
...
@@ -784,6 +842,7 @@ class RenderTable extends RenderBox {
@override
@override
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
void
paint
(
PaintingContext
context
,
Offset
offset
)
{
assert
(
_children
.
length
==
rows
*
columns
);
if
(
rows
*
columns
==
0
)
if
(
rows
*
columns
==
0
)
return
;
return
;
assert
(
_rowTops
.
length
==
rows
);
assert
(
_rowTops
.
length
==
rows
);
...
@@ -797,6 +856,7 @@ class RenderTable extends RenderBox {
...
@@ -797,6 +856,7 @@ class RenderTable extends RenderBox {
Rect
bounds
=
offset
&
size
;
Rect
bounds
=
offset
&
size
;
Canvas
canvas
=
context
.
canvas
;
Canvas
canvas
=
context
.
canvas
;
canvas
.
saveLayer
(
bounds
,
new
Paint
());
canvas
.
saveLayer
(
bounds
,
new
Paint
());
if
(
border
!=
null
)
{
switch
(
border
.
verticalInside
.
style
)
{
switch
(
border
.
verticalInside
.
style
)
{
case
BorderStyle
.
solid
:
case
BorderStyle
.
solid
:
Paint
paint
=
new
Paint
()
Paint
paint
=
new
Paint
()
...
@@ -828,6 +888,7 @@ class RenderTable extends RenderBox {
...
@@ -828,6 +888,7 @@ class RenderTable extends RenderBox {
case
BorderStyle
.
none
:
break
;
case
BorderStyle
.
none
:
break
;
}
}
border
.
paint
(
canvas
,
bounds
);
border
.
paint
(
canvas
,
bounds
);
}
canvas
.
restore
();
canvas
.
restore
();
}
}
...
@@ -851,6 +912,9 @@ class RenderTable extends RenderBox {
...
@@ -851,6 +912,9 @@ class RenderTable extends RenderBox {
StringBuffer
result
=
new
StringBuffer
();
StringBuffer
result
=
new
StringBuffer
();
result
.
writeln
(
'
$prefix
\
u2502'
);
result
.
writeln
(
'
$prefix
\
u2502'
);
int
lastIndex
=
_children
.
length
-
1
;
int
lastIndex
=
_children
.
length
-
1
;
if
(
lastIndex
<
0
)
{
result
.
writeln
(
'
$prefix
\
u2514
\
u2500table is empty'
);
}
else
{
for
(
int
y
=
0
;
y
<
rows
;
y
+=
1
)
{
for
(
int
y
=
0
;
y
<
rows
;
y
+=
1
)
{
for
(
int
x
=
0
;
x
<
columns
;
x
+=
1
)
{
for
(
int
x
=
0
;
x
<
columns
;
x
+=
1
)
{
final
int
xy
=
x
+
y
*
columns
;
final
int
xy
=
x
+
y
*
columns
;
...
@@ -870,6 +934,7 @@ class RenderTable extends RenderBox {
...
@@ -870,6 +934,7 @@ class RenderTable extends RenderBox {
}
}
}
}
}
}
}
return
result
.
toString
();
return
result
.
toString
();
}
}
}
}
packages/flutter/lib/src/widgets/basic.dart
View file @
f4603f76
...
@@ -15,21 +15,19 @@ export 'package:flutter/painting.dart';
...
@@ -15,21 +15,19 @@ export 'package:flutter/painting.dart';
export
'package:flutter/rendering.dart'
show
export
'package:flutter/rendering.dart'
show
Axis
,
Axis
,
BoxConstraints
,
BoxConstraints
,
CrossAxisAlignment
,
CustomClipper
,
CustomClipper
,
CustomPainter
,
CustomPainter
,
FixedColumnCountGridDelegate
,
FixedColumnCountGridDelegate
,
CrossAxisAlignment
,
FlexDirection
,
FlexDirection
,
MainAxisAlignment
,
FractionalOffsetTween
,
FractionalOffsetTween
,
GridDelegate
,
GridDelegate
,
GridDelegateWithInOrderChildPlacement
,
GridDelegateWithInOrderChildPlacement
,
GridSpecification
,
GridSpecification
,
HitTestBehavior
,
HitTestBehavior
,
MainAxisAlignment
,
MaxTileWidthGridDelegate
,
MaxTileWidthGridDelegate
,
MultiChildLayoutDelegate
,
MultiChildLayoutDelegate
,
SingleChildLayoutDelegate
,
RenderObjectPainter
,
PaintingContext
,
PaintingContext
,
PlainTextSpan
,
PlainTextSpan
,
PointerCancelEvent
,
PointerCancelEvent
,
...
@@ -42,7 +40,9 @@ export 'package:flutter/rendering.dart' show
...
@@ -42,7 +40,9 @@ export 'package:flutter/rendering.dart' show
PointerUpEvent
,
PointerUpEvent
,
PointerUpEventListener
,
PointerUpEventListener
,
RelativeRect
,
RelativeRect
,
RenderObjectPainter
,
ShaderCallback
,
ShaderCallback
,
SingleChildLayoutDelegate
,
ValueChanged
,
ValueChanged
,
ViewportAnchor
,
ViewportAnchor
,
ViewportDimensions
,
ViewportDimensions
,
...
...
packages/flutter/lib/src/widgets/framework.dart
View file @
f4603f76
...
@@ -20,6 +20,8 @@ export 'package:flutter/services.dart' show FlutterError;
...
@@ -20,6 +20,8 @@ export 'package:flutter/services.dart' show FlutterError;
/// original Widget's Key.
/// original Widget's Key.
///
///
/// Keys must be unique amongst the Elements with the same parent.
/// Keys must be unique amongst the Elements with the same parent.
///
/// Subclasses of Key should either subclass [LocalKey] or [GlobalKey].
abstract
class
Key
{
abstract
class
Key
{
/// Construct a ValueKey<String> with the given String.
/// Construct a ValueKey<String> with the given String.
/// This is the simplest way to create keys.
/// This is the simplest way to create keys.
...
@@ -29,12 +31,18 @@ abstract class Key {
...
@@ -29,12 +31,18 @@ abstract class Key {
const
Key
.
constructor
();
// so that subclasses can call us, since the Key() factory constructor shadows the implicit constructor
const
Key
.
constructor
();
// so that subclasses can call us, since the Key() factory constructor shadows the implicit constructor
}
}
/// A key that is not a [GlobalKey].
abstract
class
LocalKey
extends
Key
{
/// Default constructor, used by subclasses.
const
LocalKey
()
:
super
.
constructor
();
}
/// A kind of [Key] that uses a value of a particular type to identify itself.
/// A kind of [Key] that uses a value of a particular type to identify itself.
///
///
/// For example, a ValueKey<String> is equal to another ValueKey<String> if
/// For example, a ValueKey<String> is equal to another ValueKey<String> if
/// their values match.
/// their values match.
class
ValueKey
<
T
>
extends
Key
{
class
ValueKey
<
T
>
extends
Local
Key
{
const
ValueKey
(
this
.
value
)
:
super
.
constructor
()
;
const
ValueKey
(
this
.
value
);
final
T
value
;
final
T
value
;
...
@@ -54,8 +62,8 @@ class ValueKey<T> extends Key {
...
@@ -54,8 +62,8 @@ class ValueKey<T> extends Key {
}
}
/// A [Key] that is only equal to itself.
/// A [Key] that is only equal to itself.
class
UniqueKey
extends
Key
{
class
UniqueKey
extends
Local
Key
{
const
UniqueKey
()
:
super
.
constructor
()
;
const
UniqueKey
();
@override
@override
String
toString
()
=>
'[
$hashCode
]'
;
String
toString
()
=>
'[
$hashCode
]'
;
...
@@ -65,8 +73,8 @@ class UniqueKey extends Key {
...
@@ -65,8 +73,8 @@ class UniqueKey extends Key {
///
///
/// Used to tie the identity of a Widget to the identity of an object used to
/// Used to tie the identity of a Widget to the identity of an object used to
/// generate that Widget.
/// generate that Widget.
class
ObjectKey
extends
Key
{
class
ObjectKey
extends
Local
Key
{
const
ObjectKey
(
this
.
value
)
:
super
.
constructor
()
;
const
ObjectKey
(
this
.
value
);
final
Object
value
;
final
Object
value
;
...
@@ -744,7 +752,7 @@ abstract class Element implements BuildContext {
...
@@ -744,7 +752,7 @@ abstract class Element implements BuildContext {
Element
updateChild
(
Element
child
,
Widget
newWidget
,
dynamic
newSlot
)
{
Element
updateChild
(
Element
child
,
Widget
newWidget
,
dynamic
newSlot
)
{
if
(
newWidget
==
null
)
{
if
(
newWidget
==
null
)
{
if
(
child
!=
null
)
if
(
child
!=
null
)
_
deactivateChild
(
child
);
deactivateChild
(
child
);
return
null
;
return
null
;
}
}
if
(
child
!=
null
)
{
if
(
child
!=
null
)
{
...
@@ -760,10 +768,10 @@ abstract class Element implements BuildContext {
...
@@ -760,10 +768,10 @@ abstract class Element implements BuildContext {
assert
(
child
.
widget
==
newWidget
);
assert
(
child
.
widget
==
newWidget
);
return
child
;
return
child
;
}
}
_
deactivateChild
(
child
);
deactivateChild
(
child
);
assert
(
child
.
_parent
==
null
);
assert
(
child
.
_parent
==
null
);
}
}
return
_
inflateWidget
(
newWidget
,
newSlot
);
return
inflateWidget
(
newWidget
,
newSlot
);
}
}
static
void
finalizeTree
()
{
static
void
finalizeTree
()
{
...
@@ -870,7 +878,7 @@ abstract class Element implements BuildContext {
...
@@ -870,7 +878,7 @@ abstract class Element implements BuildContext {
return
element
;
return
element
;
}
}
Element
_
inflateWidget
(
Widget
newWidget
,
dynamic
newSlot
)
{
Element
inflateWidget
(
Widget
newWidget
,
dynamic
newSlot
)
{
Key
key
=
newWidget
.
key
;
Key
key
=
newWidget
.
key
;
if
(
key
is
GlobalKey
)
{
if
(
key
is
GlobalKey
)
{
Element
newChild
=
_retakeInactiveElement
(
key
,
newWidget
);
Element
newChild
=
_retakeInactiveElement
(
key
,
newWidget
);
...
@@ -901,7 +909,7 @@ abstract class Element implements BuildContext {
...
@@ -901,7 +909,7 @@ abstract class Element implements BuildContext {
});
});
}
}
void
_
deactivateChild
(
Element
child
)
{
void
deactivateChild
(
Element
child
)
{
assert
(
child
!=
null
);
assert
(
child
!=
null
);
assert
(
child
.
_parent
==
this
);
assert
(
child
.
_parent
==
this
);
child
.
_parent
=
null
;
child
.
_parent
=
null
;
...
@@ -1339,7 +1347,7 @@ abstract class ComponentElement extends BuildableElement {
...
@@ -1339,7 +1347,7 @@ abstract class ComponentElement extends BuildableElement {
@override
@override
bool
detachChild
(
Element
child
)
{
bool
detachChild
(
Element
child
)
{
assert
(
child
==
_child
);
assert
(
child
==
_child
);
_
deactivateChild
(
_child
);
deactivateChild
(
_child
);
_child
=
null
;
_child
=
null
;
return
true
;
return
true
;
}
}
...
@@ -1733,7 +1741,7 @@ abstract class RenderObjectElement extends BuildableElement {
...
@@ -1733,7 +1741,7 @@ abstract class RenderObjectElement extends BuildableElement {
if
(
oldChild
.
widget
.
key
!=
null
)
if
(
oldChild
.
widget
.
key
!=
null
)
oldKeyedChildren
[
oldChild
.
widget
.
key
]
=
oldChild
;
oldKeyedChildren
[
oldChild
.
widget
.
key
]
=
oldChild
;
else
else
_
deactivateChild
(
oldChild
);
deactivateChild
(
oldChild
);
}
}
oldChildrenTop
+=
1
;
oldChildrenTop
+=
1
;
}
}
...
@@ -1795,7 +1803,7 @@ abstract class RenderObjectElement extends BuildableElement {
...
@@ -1795,7 +1803,7 @@ abstract class RenderObjectElement extends BuildableElement {
if
(
haveOldChildren
&&
oldKeyedChildren
.
isNotEmpty
)
{
if
(
haveOldChildren
&&
oldKeyedChildren
.
isNotEmpty
)
{
for
(
Element
oldChild
in
oldKeyedChildren
.
values
)
{
for
(
Element
oldChild
in
oldKeyedChildren
.
values
)
{
if
(
detachedChildren
==
null
||
!
detachedChildren
.
contains
(
oldChild
))
if
(
detachedChildren
==
null
||
!
detachedChildren
.
contains
(
oldChild
))
_
deactivateChild
(
oldChild
);
deactivateChild
(
oldChild
);
}
}
}
}
...
@@ -1897,7 +1905,7 @@ class SingleChildRenderObjectElement extends RenderObjectElement {
...
@@ -1897,7 +1905,7 @@ class SingleChildRenderObjectElement extends RenderObjectElement {
@override
@override
bool
detachChild
(
Element
child
)
{
bool
detachChild
(
Element
child
)
{
assert
(
child
==
_child
);
assert
(
child
==
_child
);
_
deactivateChild
(
_child
);
deactivateChild
(
_child
);
_child
=
null
;
_child
=
null
;
return
true
;
return
true
;
}
}
...
@@ -1984,7 +1992,7 @@ class MultiChildRenderObjectElement extends RenderObjectElement {
...
@@ -1984,7 +1992,7 @@ class MultiChildRenderObjectElement extends RenderObjectElement {
@override
@override
bool
detachChild
(
Element
child
)
{
bool
detachChild
(
Element
child
)
{
_detachedChildren
.
add
(
child
);
_detachedChildren
.
add
(
child
);
_
deactivateChild
(
child
);
deactivateChild
(
child
);
return
true
;
return
true
;
}
}
...
@@ -1994,7 +2002,7 @@ class MultiChildRenderObjectElement extends RenderObjectElement {
...
@@ -1994,7 +2002,7 @@ class MultiChildRenderObjectElement extends RenderObjectElement {
_children
=
new
List
<
Element
>(
widget
.
children
.
length
);
_children
=
new
List
<
Element
>(
widget
.
children
.
length
);
Element
previousChild
;
Element
previousChild
;
for
(
int
i
=
0
;
i
<
_children
.
length
;
++
i
)
{
for
(
int
i
=
0
;
i
<
_children
.
length
;
++
i
)
{
Element
newChild
=
_
inflateWidget
(
widget
.
children
[
i
],
previousChild
);
Element
newChild
=
inflateWidget
(
widget
.
children
[
i
],
previousChild
);
_children
[
i
]
=
newChild
;
_children
[
i
]
=
newChild
;
previousChild
=
newChild
;
previousChild
=
newChild
;
}
}
...
...
packages/flutter/lib/src/widgets/table.dart
0 → 100644
View file @
f4603f76
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'dart:collection'
;
import
'package:flutter/rendering.dart'
;
import
'debug.dart'
;
import
'framework.dart'
;
export
'package:flutter/rendering.dart'
show
FixedColumnWidth
,
FlexColumnWidth
,
FractionColumnWidth
,
IntrinsicColumnWidth
,
MaxColumnWidth
,
MinColumnWidth
,
TableBorder
,
TableCellVerticalAlignment
,
TableColumnWidth
;
class
TableRow
{
const
TableRow
({
this
.
key
,
this
.
children
});
final
LocalKey
key
;
final
List
<
Widget
>
children
;
}
class
_TableElementRow
{
const
_TableElementRow
({
this
.
key
,
this
.
children
});
final
LocalKey
key
;
final
List
<
Element
>
children
;
}
/// Uses the table layout algorithm for its children.
///
/// For details about the table layout algorithm, see [RenderTable].
/// To control the alignment of children, see [TableCell].
class
Table
extends
RenderObjectWidget
{
Table
({
Key
key
,
this
.
children
:
const
<
TableRow
>[],
this
.
columnWidths
,
this
.
defaultColumnWidth
:
const
FlexColumnWidth
(
1.0
),
this
.
border
,
this
.
defaultVerticalAlignment
:
TableCellVerticalAlignment
.
top
,
this
.
textBaseline
})
:
super
(
key:
key
)
{
assert
(
children
!=
null
);
assert
(
defaultColumnWidth
!=
null
);
assert
(
defaultVerticalAlignment
!=
null
);
assert
(()
{
List
<
Widget
>
flatChildren
=
children
.
expand
((
TableRow
row
)
=>
row
.
children
).
toList
(
growable:
false
);
return
!
debugChildrenHaveDuplicateKeys
(
this
,
flatChildren
);
});
assert
(!
children
.
any
((
TableRow
row1
)
=>
row1
.
key
!=
null
&&
children
.
any
((
TableRow
row2
)
=>
row1
!=
row2
&&
row1
.
key
==
row2
.
key
)));
}
final
List
<
TableRow
>
children
;
final
Map
<
int
,
TableColumnWidth
>
columnWidths
;
final
TableColumnWidth
defaultColumnWidth
;
final
TableBorder
border
;
final
TableCellVerticalAlignment
defaultVerticalAlignment
;
final
TextBaseline
textBaseline
;
@override
_TableElement
createElement
()
=>
new
_TableElement
(
this
);
@override
RenderTable
createRenderObject
(
BuildContext
context
)
{
return
new
RenderTable
(
columns:
children
.
length
>
0
?
children
[
0
].
children
.
length
:
0
,
rows:
children
.
length
,
columnWidths:
columnWidths
,
defaultColumnWidth:
defaultColumnWidth
,
border:
border
,
defaultVerticalAlignment:
defaultVerticalAlignment
,
textBaseline:
textBaseline
);
}
@override
void
updateRenderObject
(
BuildContext
context
,
RenderTable
renderObject
)
{
assert
(
renderObject
.
columns
==
(
children
.
length
>
0
?
children
[
0
].
children
.
length
:
0
));
assert
(
renderObject
.
rows
==
children
.
length
);
renderObject
..
columnWidths
=
columnWidths
..
defaultColumnWidth
=
defaultColumnWidth
..
border
=
border
..
defaultVerticalAlignment
=
defaultVerticalAlignment
..
textBaseline
=
textBaseline
;
}
}
class
_TableElement
extends
RenderObjectElement
{
_TableElement
(
Table
widget
)
:
super
(
widget
);
@override
Table
get
widget
=>
super
.
widget
;
@override
RenderTable
get
renderObject
=>
super
.
renderObject
;
// This class ignores the child's slot entirely.
// Instead of doing incremental updates to the child list, it replaces the entire list each frame.
List
<
_TableElementRow
>
_children
=
const
<
_TableElementRow
>[];
bool
_debugWillReattachChildren
=
false
;
@override
void
mount
(
Element
parent
,
dynamic
newSlot
)
{
super
.
mount
(
parent
,
newSlot
);
assert
(!
_debugWillReattachChildren
);
assert
(()
{
_debugWillReattachChildren
=
true
;
return
true
;
});
_children
=
widget
.
children
.
map
((
TableRow
row
)
{
return
new
_TableElementRow
(
key:
row
.
key
,
children:
row
.
children
.
map
((
Widget
child
)
=>
inflateWidget
(
child
,
null
)).
toList
(
growable:
false
)
);
}).
toList
(
growable:
false
);
assert
(()
{
_debugWillReattachChildren
=
false
;
return
true
;
});
_updateRenderObjectChildren
();
}
@override
void
insertChildRenderObject
(
RenderObject
child
,
Element
slot
)
{
assert
(
_debugWillReattachChildren
);
renderObject
.
setupParentData
(
child
);
}
@override
void
moveChildRenderObject
(
RenderObject
child
,
dynamic
slot
)
{
assert
(
_debugWillReattachChildren
);
}
@override
void
removeChildRenderObject
(
RenderObject
child
)
{
assert
(
_debugWillReattachChildren
);
TableCellParentData
childParentData
=
child
.
parentData
;
renderObject
.
setChild
(
childParentData
.
x
,
childParentData
.
y
,
null
);
}
final
Set
<
Element
>
_detachedChildren
=
new
HashSet
<
Element
>();
@override
void
update
(
Table
newWidget
)
{
assert
(!
_debugWillReattachChildren
);
assert
(()
{
_debugWillReattachChildren
=
true
;
return
true
;
});
Map
<
LocalKey
,
List
<
Element
>>
oldKeyedRows
=
new
Map
<
LocalKey
,
List
<
Element
>>.
fromIterable
(
_children
.
where
((
_TableElementRow
row
)
=>
row
.
key
!=
null
),
key:
(
_TableElementRow
row
)
=>
row
.
key
,
value:
(
_TableElementRow
row
)
=>
row
.
children
);
Iterator
<
_TableElementRow
>
oldUnkeyedRows
=
_children
.
where
((
_TableElementRow
row
)
=>
row
.
key
==
null
).
iterator
;
List
<
_TableElementRow
>
newChildren
=
<
_TableElementRow
>[];
Set
<
List
<
Element
>>
taken
=
new
Set
<
List
<
Element
>>();
for
(
TableRow
row
in
newWidget
.
children
)
{
List
<
Element
>
oldChildren
;
if
(
row
.
key
!=
null
&&
oldKeyedRows
.
containsKey
(
row
.
key
))
{
oldChildren
=
oldKeyedRows
[
row
.
key
];
taken
.
add
(
oldChildren
);
}
else
if
(
row
.
key
==
null
&&
oldUnkeyedRows
.
moveNext
())
{
oldChildren
=
oldUnkeyedRows
.
current
.
children
;
}
else
{
oldChildren
=
const
<
Element
>[];
}
newChildren
.
add
(
new
_TableElementRow
(
key:
row
.
key
,
children:
updateChildren
(
oldChildren
,
row
.
children
,
detachedChildren:
_detachedChildren
)
));
}
while
(
oldUnkeyedRows
.
moveNext
())
updateChildren
(
oldUnkeyedRows
.
current
.
children
,
const
<
Widget
>[],
detachedChildren:
_detachedChildren
);
for
(
List
<
Element
>
oldChildren
in
oldKeyedRows
.
values
.
where
((
List
<
Element
>
list
)
=>
!
taken
.
contains
(
list
)))
updateChildren
(
oldChildren
,
const
<
Widget
>[],
detachedChildren:
_detachedChildren
);
assert
(()
{
_debugWillReattachChildren
=
false
;
return
true
;
});
_children
=
newChildren
;
_updateRenderObjectChildren
();
_detachedChildren
.
clear
();
super
.
update
(
newWidget
);
assert
(
widget
==
newWidget
);
}
void
_updateRenderObjectChildren
()
{
assert
(
renderObject
!=
null
);
renderObject
.
setFlatChildren
(
_children
.
length
>
0
?
_children
[
0
].
children
.
length
:
0
,
_children
.
expand
((
_TableElementRow
row
)
=>
row
.
children
.
map
((
Element
child
)
=>
child
.
renderObject
)).
toList
()
);
}
@override
void
visitChildren
(
ElementVisitor
visitor
)
{
for
(
Element
child
in
_children
.
expand
((
_TableElementRow
row
)
=>
row
.
children
))
{
if
(!
_detachedChildren
.
contains
(
child
))
visitor
(
child
);
}
}
@override
bool
detachChild
(
Element
child
)
{
_detachedChildren
.
add
(
child
);
deactivateChild
(
child
);
return
true
;
}
}
class
TableCell
extends
ParentDataWidget
<
Table
>
{
TableCell
({
Key
key
,
this
.
verticalAlignment
,
Widget
child
})
:
super
(
key:
key
,
child:
child
);
final
TableCellVerticalAlignment
verticalAlignment
;
@override
void
applyParentData
(
RenderObject
renderObject
)
{
final
TableCellParentData
parentData
=
renderObject
.
parentData
;
if
(
parentData
.
verticalAlignment
!=
verticalAlignment
)
{
parentData
.
verticalAlignment
=
verticalAlignment
;
AbstractNode
targetParent
=
renderObject
.
parent
;
if
(
targetParent
is
RenderObject
)
targetParent
.
markNeedsLayout
();
}
}
@override
void
debugFillDescription
(
List
<
String
>
description
)
{
super
.
debugFillDescription
(
description
);
description
.
add
(
'verticalAlignment:
$verticalAlignment
'
);
}
}
packages/flutter/lib/widgets.dart
View file @
f4603f76
...
@@ -44,6 +44,7 @@ export 'src/widgets/scrollable_list.dart';
...
@@ -44,6 +44,7 @@ export 'src/widgets/scrollable_list.dart';
export
'src/widgets/scrollable.dart'
;
export
'src/widgets/scrollable.dart'
;
export
'src/widgets/semantics_debugger.dart'
;
export
'src/widgets/semantics_debugger.dart'
;
export
'src/widgets/status_transitions.dart'
;
export
'src/widgets/status_transitions.dart'
;
export
'src/widgets/table.dart'
;
export
'src/widgets/title.dart'
;
export
'src/widgets/title.dart'
;
export
'src/widgets/transitions.dart'
;
export
'src/widgets/transitions.dart'
;
export
'src/widgets/unique_widget.dart'
;
export
'src/widgets/unique_widget.dart'
;
...
...
packages/flutter/test/rendering/table_test.dart
View file @
f4603f76
...
@@ -55,4 +55,20 @@ void main() {
...
@@ -55,4 +55,20 @@ void main() {
expect
(
table
.
size
,
equals
(
new
Size
(
800.0
,
230.0
)));
expect
(
table
.
size
,
equals
(
new
Size
(
800.0
,
230.0
)));
});
});
test
(
'Table test: removing cells'
,
()
{
RenderTable
table
;
RenderBox
child
;
table
=
new
RenderTable
(
columns:
5
,
rows:
5
);
table
.
setChild
(
4
,
4
,
child
=
sizedBox
(
10.0
,
10.0
));
layout
(
table
);
expect
(
child
.
attached
,
isTrue
);
table
.
rows
=
4
;
expect
(
child
.
attached
,
isFalse
);
});
}
}
packages/flutter/test/widget/table_test.dart
0 → 100644
View file @
f4603f76
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import
'package:flutter_test/flutter_test.dart'
;
import
'package:flutter/rendering.dart'
;
import
'package:flutter/widgets.dart'
;
import
'package:test/test.dart'
;
void
main
(
)
{
test
(
'Table widget - control test'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
tester
.
pumpWidget
(
new
Table
(
children:
<
TableRow
>[
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'AAAAAA'
),
new
Text
(
'B'
),
new
Text
(
'C'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'D'
),
new
Text
(
'EEE'
),
new
Text
(
'F'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'G'
),
new
Text
(
'H'
),
new
Text
(
'III'
)
]
),
]
)
);
RenderBox
boxA
=
tester
.
findText
(
'AAAAAA'
).
findRenderObject
();
RenderBox
boxD
=
tester
.
findText
(
'D'
).
findRenderObject
();
RenderBox
boxG
=
tester
.
findText
(
'G'
).
findRenderObject
();
RenderBox
boxB
=
tester
.
findText
(
'B'
).
findRenderObject
();
expect
(
boxA
.
size
,
equals
(
boxD
.
size
));
expect
(
boxA
.
size
,
equals
(
boxG
.
size
));
expect
(
boxA
.
size
,
equals
(
boxB
.
size
));
});
});
test
(
'Table widget - changing table dimensions'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
tester
.
pumpWidget
(
new
Table
(
children:
<
TableRow
>[
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'A'
),
new
Text
(
'B'
),
new
Text
(
'C'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'D'
),
new
Text
(
'E'
),
new
Text
(
'F'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'G'
),
new
Text
(
'H'
),
new
Text
(
'I'
)
]
),
]
)
);
RenderBox
boxA1
=
tester
.
findText
(
'A'
).
findRenderObject
();
RenderBox
boxG1
=
tester
.
findText
(
'G'
).
findRenderObject
();
expect
(
boxA1
,
isNotNull
);
expect
(
boxG1
,
isNotNull
);
tester
.
pumpWidget
(
new
Table
(
children:
<
TableRow
>[
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'a'
),
new
Text
(
'b'
),
new
Text
(
'c'
),
new
Text
(
'd'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'e'
),
new
Text
(
'f'
),
new
Text
(
'g'
),
new
Text
(
'h'
)
]
),
]
)
);
RenderBox
boxA2
=
tester
.
findText
(
'a'
).
findRenderObject
();
RenderBox
boxG2
=
tester
.
findText
(
'g'
).
findRenderObject
();
expect
(
boxA2
,
isNotNull
);
expect
(
boxG2
,
isNotNull
);
expect
(
boxA1
,
equals
(
boxA2
));
expect
(
boxG1
,
isNot
(
equals
(
boxG2
)));
});
});
test
(
'Table widget - repump test'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
tester
.
pumpWidget
(
new
Table
(
children:
<
TableRow
>[
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'AAAAAA'
),
new
Text
(
'B'
),
new
Text
(
'C'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'D'
),
new
Text
(
'EEE'
),
new
Text
(
'F'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'G'
),
new
Text
(
'H'
),
new
Text
(
'III'
)
]
),
]
)
);
tester
.
pumpWidget
(
new
Table
(
children:
<
TableRow
>[
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'AAA'
),
new
Text
(
'B'
),
new
Text
(
'C'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'D'
),
new
Text
(
'E'
),
new
Text
(
'FFFFFF'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'G'
),
new
Text
(
'H'
),
new
Text
(
'III'
)
]
),
]
)
);
RenderBox
boxA
=
tester
.
findText
(
'AAA'
).
findRenderObject
();
RenderBox
boxD
=
tester
.
findText
(
'D'
).
findRenderObject
();
RenderBox
boxG
=
tester
.
findText
(
'G'
).
findRenderObject
();
RenderBox
boxB
=
tester
.
findText
(
'B'
).
findRenderObject
();
expect
(
boxA
.
size
,
equals
(
boxD
.
size
));
expect
(
boxA
.
size
,
equals
(
boxG
.
size
));
expect
(
boxA
.
size
,
equals
(
boxB
.
size
));
});
});
test
(
'Table widget - intrinsic sizing test'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
tester
.
pumpWidget
(
new
Table
(
defaultColumnWidth:
const
IntrinsicColumnWidth
(),
children:
<
TableRow
>[
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'AAA'
),
new
Text
(
'B'
),
new
Text
(
'C'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'D'
),
new
Text
(
'E'
),
new
Text
(
'FFFFFF'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'G'
),
new
Text
(
'H'
),
new
Text
(
'III'
)
]
),
]
)
);
RenderBox
boxA
=
tester
.
findText
(
'AAA'
).
findRenderObject
();
RenderBox
boxD
=
tester
.
findText
(
'D'
).
findRenderObject
();
RenderBox
boxG
=
tester
.
findText
(
'G'
).
findRenderObject
();
RenderBox
boxB
=
tester
.
findText
(
'B'
).
findRenderObject
();
expect
(
boxA
.
size
,
equals
(
boxD
.
size
));
expect
(
boxA
.
size
,
equals
(
boxG
.
size
));
expect
(
boxA
.
size
.
width
,
greaterThan
(
boxB
.
size
.
width
));
expect
(
boxA
.
size
.
height
,
equals
(
boxB
.
size
.
height
));
});
});
test
(
'Table widget - intrinsic sizing test, resizing'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
tester
.
pumpWidget
(
new
Table
(
defaultColumnWidth:
const
IntrinsicColumnWidth
(),
children:
<
TableRow
>[
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'AAAAAA'
),
new
Text
(
'B'
),
new
Text
(
'C'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'D'
),
new
Text
(
'EEE'
),
new
Text
(
'F'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'G'
),
new
Text
(
'H'
),
new
Text
(
'III'
)
]
),
]
)
);
tester
.
pumpWidget
(
new
Table
(
defaultColumnWidth:
const
IntrinsicColumnWidth
(),
children:
<
TableRow
>[
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'A'
),
new
Text
(
'B'
),
new
Text
(
'C'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'D'
),
new
Text
(
'EEE'
),
new
Text
(
'F'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'G'
),
new
Text
(
'H'
),
new
Text
(
'III'
)
]
),
]
)
);
RenderBox
boxA
=
tester
.
findText
(
'A'
).
findRenderObject
();
RenderBox
boxD
=
tester
.
findText
(
'D'
).
findRenderObject
();
RenderBox
boxG
=
tester
.
findText
(
'G'
).
findRenderObject
();
RenderBox
boxB
=
tester
.
findText
(
'B'
).
findRenderObject
();
expect
(
boxA
.
size
,
equals
(
boxD
.
size
));
expect
(
boxA
.
size
,
equals
(
boxG
.
size
));
expect
(
boxA
.
size
.
width
,
lessThan
(
boxB
.
size
.
width
));
expect
(
boxA
.
size
.
height
,
equals
(
boxB
.
size
.
height
));
});
});
test
(
'Table widget - intrinsic sizing test, changing column widths'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
tester
.
pumpWidget
(
new
Table
(
children:
<
TableRow
>[
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'AAA'
),
new
Text
(
'B'
),
new
Text
(
'C'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'D'
),
new
Text
(
'E'
),
new
Text
(
'FFFFFF'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'G'
),
new
Text
(
'H'
),
new
Text
(
'III'
)
]
),
]
)
);
tester
.
pumpWidget
(
new
Table
(
defaultColumnWidth:
const
IntrinsicColumnWidth
(),
children:
<
TableRow
>[
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'AAA'
),
new
Text
(
'B'
),
new
Text
(
'C'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'D'
),
new
Text
(
'E'
),
new
Text
(
'FFFFFF'
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'G'
),
new
Text
(
'H'
),
new
Text
(
'III'
)
]
),
]
)
);
RenderBox
boxA
=
tester
.
findText
(
'AAA'
).
findRenderObject
();
RenderBox
boxD
=
tester
.
findText
(
'D'
).
findRenderObject
();
RenderBox
boxG
=
tester
.
findText
(
'G'
).
findRenderObject
();
RenderBox
boxB
=
tester
.
findText
(
'B'
).
findRenderObject
();
expect
(
boxA
.
size
,
equals
(
boxD
.
size
));
expect
(
boxA
.
size
,
equals
(
boxG
.
size
));
expect
(
boxA
.
size
.
width
,
greaterThan
(
boxB
.
size
.
width
));
expect
(
boxA
.
size
.
height
,
equals
(
boxB
.
size
.
height
));
});
});
test
(
'Table widget - moving test'
,
()
{
testWidgets
((
WidgetTester
tester
)
{
List
<
BuildContext
>
contexts
=
<
BuildContext
>[];
tester
.
pumpWidget
(
new
Table
(
children:
<
TableRow
>[
new
TableRow
(
key:
new
ValueKey
<
int
>(
1
),
children:
<
Widget
>[
new
StatefulBuilder
(
builder:
(
BuildContext
context
,
StateSetter
setState
)
{
contexts
.
add
(
context
);
return
new
Text
(
'A'
);
}
)
]
),
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'b'
)
]
),
]
)
);
tester
.
pumpWidget
(
new
Table
(
children:
<
TableRow
>[
new
TableRow
(
children:
<
Widget
>[
new
Text
(
'b'
)
]
),
new
TableRow
(
key:
new
ValueKey
<
int
>(
1
),
children:
<
Widget
>[
new
StatefulBuilder
(
builder:
(
BuildContext
context
,
StateSetter
setState
)
{
contexts
.
add
(
context
);
return
new
Text
(
'A'
);
}
)
]
),
]
)
);
expect
(
contexts
.
length
,
equals
(
2
));
expect
(
contexts
[
0
],
equals
(
contexts
[
1
]));
});
});
// TODO(ianh): Test handling of TableCell object
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment