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
9e082f6c
Unverified
Commit
9e082f6c
authored
Jun 23, 2021
by
Hans Muller
Committed by
GitHub
Jun 23, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add OverflowBar.alignment property (#85050)
parent
b79dd40b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
154 additions
and
6 deletions
+154
-6
overflow_bar.dart
packages/flutter/lib/src/widgets/overflow_bar.dart
+84
-6
overflow_bar_test.dart
packages/flutter/test/widgets/overflow_bar_test.dart
+70
-0
No files found.
packages/flutter/lib/src/widgets/overflow_bar.dart
View file @
9e082f6c
...
...
@@ -103,6 +103,7 @@ class OverflowBar extends MultiChildRenderObjectWidget {
OverflowBar
({
Key
?
key
,
this
.
spacing
=
0.0
,
this
.
alignment
,
this
.
overflowSpacing
=
0.0
,
this
.
overflowAlignment
=
OverflowBarAlignment
.
start
,
this
.
overflowDirection
=
VerticalDirection
.
down
,
...
...
@@ -125,6 +126,33 @@ class OverflowBar extends MultiChildRenderObjectWidget {
/// Defaults to 0.0.
final
double
spacing
;
/// Defines the [children]'s horizontal layout according to the same
/// rules as for [Row.mainAxisAlignment].
///
/// If this property is non-null, and the [children], separated by
/// [spacing], fit within the available width, then the overflow
/// bar will be as wide as possible. If the children do not fit
/// within the available width, then this property is ignored and
/// [overflowAlignment] applies instead.
///
/// If this property is null (the default) then the overflow bar
/// will be no wider than needed to layout the [children] separated
/// by [spacing], modulo the incoming constraints.
///
/// If [alignment] is one of [MainAxisAlignment.spaceAround],
/// [MainAxisAlignment.spaceBetween], or
/// [MainAxisAlignment.spaceEvenly], then the [spacing] parameter is
/// only used to see if the horizontal layout will overflow.
///
/// Defaults to null.
///
/// See also:
///
/// * [overflowAlignment], the horizontal alignment of the [children] within
/// the vertical "overflow" layout.
///
final
MainAxisAlignment
?
alignment
;
/// The height of the gap between [children] in the vertical
/// "overflow" layout.
///
...
...
@@ -163,6 +191,9 @@ class OverflowBar extends MultiChildRenderObjectWidget {
///
/// See also:
///
/// * [alignment], which defines the [children]'s horizontal layout
/// (according to the same rules as for [Row.mainAxisAlignment]) when
/// the children, separated by [spacing], fit within the available space.
/// * [overflowDirection], which defines the order that the
/// [OverflowBar]'s children appear in, if the horizontal layout
/// overflows.
...
...
@@ -221,6 +252,7 @@ class OverflowBar extends MultiChildRenderObjectWidget {
RenderObject
createRenderObject
(
BuildContext
context
)
{
return
_RenderOverflowBar
(
spacing:
spacing
,
alignment:
alignment
,
overflowSpacing:
overflowSpacing
,
overflowAlignment:
overflowAlignment
,
overflowDirection:
overflowDirection
,
...
...
@@ -233,6 +265,7 @@ class OverflowBar extends MultiChildRenderObjectWidget {
void
updateRenderObject
(
BuildContext
context
,
RenderObject
renderObject
)
{
(
renderObject
as
_RenderOverflowBar
)
..
spacing
=
spacing
..
alignment
=
alignment
..
overflowSpacing
=
overflowSpacing
..
overflowAlignment
=
overflowAlignment
..
overflowDirection
=
overflowDirection
...
...
@@ -244,6 +277,7 @@ class OverflowBar extends MultiChildRenderObjectWidget {
void
debugFillProperties
(
DiagnosticPropertiesBuilder
properties
)
{
super
.
debugFillProperties
(
properties
);
properties
.
add
(
DoubleProperty
(
'spacing'
,
spacing
,
defaultValue:
0
));
properties
.
add
(
EnumProperty
<
MainAxisAlignment
>(
'alignment'
,
alignment
,
defaultValue:
null
));
properties
.
add
(
DoubleProperty
(
'overflowSpacing'
,
overflowSpacing
,
defaultValue:
0
));
properties
.
add
(
EnumProperty
<
OverflowBarAlignment
>(
'overflowAlignment'
,
overflowAlignment
,
defaultValue:
OverflowBarAlignment
.
start
));
properties
.
add
(
EnumProperty
<
VerticalDirection
>(
'overflowDirection'
,
overflowDirection
,
defaultValue:
VerticalDirection
.
down
));
...
...
@@ -259,6 +293,7 @@ class _RenderOverflowBar extends RenderBox
_RenderOverflowBar
({
List
<
RenderBox
>?
children
,
double
spacing
=
0.0
,
MainAxisAlignment
?
alignment
,
double
overflowSpacing
=
0.0
,
OverflowBarAlignment
overflowAlignment
=
OverflowBarAlignment
.
start
,
VerticalDirection
overflowDirection
=
VerticalDirection
.
down
,
...
...
@@ -270,6 +305,7 @@ class _RenderOverflowBar extends RenderBox
assert
(
textDirection
!=
null
),
assert
(
clipBehavior
!=
null
),
_spacing
=
spacing
,
_alignment
=
alignment
,
_overflowSpacing
=
overflowSpacing
,
_overflowAlignment
=
overflowAlignment
,
_overflowDirection
=
overflowDirection
,
...
...
@@ -288,6 +324,15 @@ class _RenderOverflowBar extends RenderBox
markNeedsLayout
();
}
MainAxisAlignment
?
get
alignment
=>
_alignment
;
MainAxisAlignment
?
_alignment
;
set
alignment
(
MainAxisAlignment
?
value
)
{
if
(
_alignment
==
value
)
return
;
_alignment
=
value
;
markNeedsLayout
();
}
double
get
overflowSpacing
=>
_overflowSpacing
;
double
_overflowSpacing
;
set
overflowSpacing
(
double
value
)
{
...
...
@@ -456,7 +501,8 @@ class _RenderOverflowBar extends RenderBox
if
(
actualWidth
>
constraints
.
maxWidth
)
{
return
constraints
.
constrain
(
Size
(
constraints
.
maxWidth
,
y
-
overflowSpacing
));
}
else
{
return
constraints
.
constrain
(
Size
(
actualWidth
,
maxChildHeight
));
final
double
overallWidth
=
alignment
==
null
?
actualWidth
:
constraints
.
maxWidth
;
return
constraints
.
constrain
(
Size
(
overallWidth
,
maxChildHeight
));
}
}
...
...
@@ -510,10 +556,42 @@ class _RenderOverflowBar extends RenderBox
}
size
=
constraints
.
constrain
(
Size
(
constraints
.
maxWidth
,
y
-
overflowSpacing
));
}
else
{
// Default horizontal layout.
size
=
constraints
.
constrain
(
Size
(
actualWidth
,
maxChildHeight
));
// Default horizontal layout
child
=
firstChild
;
double
x
=
rtl
?
size
.
width
-
child
!.
size
.
width
:
0
;
final
double
firstChildWidth
=
child
!.
size
.
width
;
final
double
overallWidth
=
alignment
==
null
?
actualWidth
:
constraints
.
maxWidth
;
size
=
constraints
.
constrain
(
Size
(
overallWidth
,
maxChildHeight
));
late
double
x
;
// initial value: origin of the first child
double
layoutSpacing
=
spacing
;
// space between children
switch
(
alignment
)
{
case
null
:
x
=
rtl
?
size
.
width
-
firstChildWidth
:
0
;
break
;
case
MainAxisAlignment
.
start
:
x
=
rtl
?
size
.
width
-
firstChildWidth
:
0
;
break
;
case
MainAxisAlignment
.
center
:
final
double
halfRemainingWidth
=
(
size
.
width
-
actualWidth
)
/
2
;
x
=
rtl
?
size
.
width
-
halfRemainingWidth
-
firstChildWidth
:
halfRemainingWidth
;
break
;
case
MainAxisAlignment
.
end
:
x
=
rtl
?
actualWidth
-
firstChildWidth
:
size
.
width
-
actualWidth
;
break
;
case
MainAxisAlignment
.
spaceBetween
:
layoutSpacing
=
(
size
.
width
-
childrenWidth
)
/
(
childCount
-
1
);
x
=
rtl
?
size
.
width
-
firstChildWidth
:
0
;
break
;
case
MainAxisAlignment
.
spaceAround
:
layoutSpacing
=
childCount
>
0
?
(
size
.
width
-
childrenWidth
)
/
childCount
:
0
;
x
=
rtl
?
size
.
width
-
layoutSpacing
/
2
-
firstChildWidth
:
layoutSpacing
/
2
;
break
;
case
MainAxisAlignment
.
spaceEvenly
:
layoutSpacing
=
(
size
.
width
-
childrenWidth
)
/
(
childCount
+
1
);
x
=
rtl
?
size
.
width
-
layoutSpacing
-
firstChildWidth
:
layoutSpacing
;
break
;
}
while
(
child
!=
null
)
{
final
_OverflowBarParentData
childParentData
=
child
.
parentData
!
as
_OverflowBarParentData
;
childParentData
.
offset
=
Offset
(
x
,
(
maxChildHeight
-
child
.
size
.
height
)
/
2
);
...
...
@@ -522,11 +600,11 @@ class _RenderOverflowBar extends RenderBox
// the origin of the next child for RTL: subtract the width of the next
// child (if there is one).
if
(!
rtl
)
{
x
+=
child
.
size
.
width
+
s
pacing
;
x
+=
child
.
size
.
width
+
layoutS
pacing
;
}
child
=
childAfter
(
child
);
if
(
rtl
&&
child
!=
null
)
{
x
-=
child
.
size
.
width
+
s
pacing
;
x
-=
child
.
size
.
width
+
layoutS
pacing
;
}
}
}
...
...
packages/flutter/test/widgets/overflow_bar_test.dart
View file @
9e082f6c
...
...
@@ -9,6 +9,7 @@ void main() {
testWidgets
(
'OverflowBar documented defaults'
,
(
WidgetTester
tester
)
async
{
final
OverflowBar
bar
=
OverflowBar
();
expect
(
bar
.
spacing
,
0
);
expect
(
bar
.
alignment
,
null
);
expect
(
bar
.
overflowSpacing
,
0
);
expect
(
bar
.
overflowDirection
,
VerticalDirection
.
down
);
expect
(
bar
.
textDirection
,
null
);
...
...
@@ -271,4 +272,73 @@ void main() {
expect
(
tester
.
getTopLeft
(
find
.
byKey
(
key1
)).
dx
,
680
);
expect
(
tester
.
getTopLeft
(
find
.
byKey
(
key2
)).
dx
,
600
);
});
testWidgets
(
'OverflowBar with alignment should match Row with mainAxisAlignment'
,
(
WidgetTester
tester
)
async
{
final
Key
key0
=
UniqueKey
();
final
Key
key1
=
UniqueKey
();
final
Key
key2
=
UniqueKey
();
// This list of children appears in a Row and an OverflowBar, so each
// find.byKey() for key0, key1, key2 returns two widgets.
final
List
<
Widget
>
children
=
<
Widget
>[
SizedBox
(
key:
key0
,
width:
50
,
height:
50
),
SizedBox
(
key:
key1
,
width:
70
,
height:
50
),
SizedBox
(
key:
key2
,
width:
80
,
height:
50
),
];
const
List
<
MainAxisAlignment
>
allAlignments
=
<
MainAxisAlignment
>[
MainAxisAlignment
.
start
,
MainAxisAlignment
.
center
,
MainAxisAlignment
.
end
,
MainAxisAlignment
.
spaceBetween
,
MainAxisAlignment
.
spaceAround
,
MainAxisAlignment
.
spaceEvenly
,
];
const
List
<
TextDirection
>
allTextDirections
=
<
TextDirection
>[
TextDirection
.
ltr
,
TextDirection
.
rtl
,
];
Widget
buildFrame
(
MainAxisAlignment
alignment
,
TextDirection
textDirection
)
{
return
Directionality
(
textDirection:
textDirection
,
child:
Column
(
children:
<
Widget
>[
OverflowBar
(
alignment:
alignment
,
children:
children
,
),
Row
(
mainAxisAlignment:
alignment
,
children:
children
,
),
],
),
);
}
// Each key from key0, key1, key2 maps to one child in the OverflowBar
// and a matching child in the Row. We expect the children to be the
// same size and for their left and right edges to align.
void
testLayout
()
{
expect
(
tester
.
getSize
(
find
.
byType
(
OverflowBar
)),
const
Size
(
800
,
50
));
for
(
final
Key
key
in
<
Key
>[
key0
,
key1
,
key2
])
{
final
Finder
matchingChildren
=
find
.
byKey
(
key
);
expect
(
matchingChildren
.
evaluate
().
length
,
2
);
final
Rect
rect0
=
tester
.
getRect
(
matchingChildren
.
first
);
final
Rect
rect1
=
tester
.
getRect
(
matchingChildren
.
last
);
expect
(
rect0
.
size
,
rect1
.
size
);
expect
(
rect0
.
left
,
rect1
.
left
);
expect
(
rect0
.
right
,
rect1
.
right
);
}
}
for
(
final
MainAxisAlignment
alignment
in
allAlignments
)
{
for
(
final
TextDirection
textDirection
in
allTextDirections
)
{
await
tester
.
pumpWidget
(
buildFrame
(
alignment
,
textDirection
));
testLayout
();
}
}
});
}
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