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
01742673
Commit
01742673
authored
Jan 15, 2020
by
Shi-Hao Hong
Committed by
Flutter GitHub Bot
Jan 15, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ButtonBar.verticalDirection and AlertDialog.actionsVerticalDirection (#48728)
parent
ad9476dc
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
157 additions
and
5 deletions
+157
-5
button_bar.dart
packages/flutter/lib/src/material/button_bar.dart
+37
-4
button_bar_theme.dart
packages/flutter/lib/src/material/button_bar_theme.dart
+20
-1
dialog.dart
packages/flutter/lib/src/material/dialog.dart
+30
-0
button_bar_test.dart
packages/flutter/test/material/button_bar_test.dart
+29
-0
button_bar_theme_test.dart
packages/flutter/test/material/button_bar_theme_test.dart
+6
-0
dialog_test.dart
packages/flutter/test/material/dialog_test.dart
+35
-0
No files found.
packages/flutter/lib/src/material/button_bar.dart
View file @
01742673
...
...
@@ -64,6 +64,7 @@ class ButtonBar extends StatelessWidget {
this
.
buttonPadding
,
this
.
buttonAlignedDropdown
,
this
.
layoutBehavior
,
this
.
overflowDirection
,
this
.
children
=
const
<
Widget
>[],
})
:
assert
(
buttonMinWidth
==
null
||
buttonMinWidth
>=
0.0
),
assert
(
buttonHeight
==
null
||
buttonHeight
>=
0.0
),
...
...
@@ -126,6 +127,22 @@ class ButtonBar extends StatelessWidget {
/// If that is null, it will default [ButtonBarLayoutBehavior.padded].
final
ButtonBarLayoutBehavior
layoutBehavior
;
/// Defines the vertical direction of a [ButtonBar]'s children if it
/// overflows.
///
/// If [children] do not fit into a single row, then they
/// are arranged in a column. The first action is at the top of the
/// column if this property is set to [VerticalDirection.down], since it
/// "starts" at the top and "ends" at the bottom. On the other hand,
/// the first action will be at the bottom of the column if this
/// property is set to [VerticalDirection.up], since it "starts" at the
/// bottom and "ends" at the top.
///
/// If null then it will use the surrounding
/// [ButtonBarTheme.overflowDirection]. If that is null, it will
/// default to [VerticalDirection.down].
final
VerticalDirection
overflowDirection
;
/// The buttons to arrange horizontally.
///
/// Typically [RaisedButton] or [FlatButton] widgets.
...
...
@@ -152,6 +169,7 @@ class ButtonBar extends StatelessWidget {
child:
_ButtonBarRow
(
mainAxisAlignment:
alignment
??
barTheme
.
alignment
??
MainAxisAlignment
.
end
,
mainAxisSize:
mainAxisSize
??
barTheme
.
mainAxisSize
??
MainAxisSize
.
max
,
overflowDirection:
overflowDirection
??
barTheme
.
overflowDirection
??
VerticalDirection
.
down
,
children:
children
.
map
<
Widget
>((
Widget
child
)
{
return
Padding
(
padding:
EdgeInsets
.
symmetric
(
horizontal:
paddingUnit
),
...
...
@@ -206,7 +224,7 @@ class _ButtonBarRow extends Flex {
MainAxisAlignment
mainAxisAlignment
=
MainAxisAlignment
.
start
,
CrossAxisAlignment
crossAxisAlignment
=
CrossAxisAlignment
.
center
,
TextDirection
textDirection
,
VerticalDirection
vertical
Direction
=
VerticalDirection
.
down
,
VerticalDirection
overflow
Direction
=
VerticalDirection
.
down
,
TextBaseline
textBaseline
,
})
:
super
(
children:
children
,
...
...
@@ -215,7 +233,7 @@ class _ButtonBarRow extends Flex {
mainAxisAlignment:
mainAxisAlignment
,
crossAxisAlignment:
crossAxisAlignment
,
textDirection:
textDirection
,
verticalDirection:
vertical
Direction
,
verticalDirection:
overflow
Direction
,
textBaseline:
textBaseline
,
);
...
...
@@ -312,8 +330,16 @@ class _RenderButtonBarRow extends RenderFlex {
super
.
performLayout
();
}
else
{
final
BoxConstraints
childConstraints
=
constraints
.
copyWith
(
minWidth:
0.0
);
RenderBox
child
=
firstChild
;
RenderBox
child
;
double
currentHeight
=
0.0
;
switch
(
verticalDirection
)
{
case
VerticalDirection
.
down
:
child
=
firstChild
;
break
;
case
VerticalDirection
.
up
:
child
=
lastChild
;
break
;
}
while
(
child
!=
null
)
{
final
FlexParentData
childParentData
=
child
.
parentData
as
FlexParentData
;
...
...
@@ -357,7 +383,14 @@ class _RenderButtonBarRow extends RenderFlex {
break
;
}
currentHeight
+=
child
.
size
.
height
;
child
=
childParentData
.
nextSibling
;
switch
(
verticalDirection
)
{
case
VerticalDirection
.
down
:
child
=
childParentData
.
nextSibling
;
break
;
case
VerticalDirection
.
up
:
child
=
childParentData
.
previousSibling
;
break
;
}
}
size
=
constraints
.
constrain
(
Size
(
constraints
.
maxWidth
,
currentHeight
));
}
...
...
packages/flutter/lib/src/material/button_bar_theme.dart
View file @
01742673
...
...
@@ -38,6 +38,7 @@ class ButtonBarThemeData extends Diagnosticable {
this
.
buttonPadding
,
this
.
buttonAlignedDropdown
,
this
.
layoutBehavior
,
this
.
overflowDirection
,
})
:
assert
(
buttonMinWidth
==
null
||
buttonMinWidth
>=
0.0
),
assert
(
buttonHeight
==
null
||
buttonHeight
>=
0.0
);
...
...
@@ -97,6 +98,18 @@ class ButtonBarThemeData extends Diagnosticable {
/// constraint or with padding.
final
ButtonBarLayoutBehavior
layoutBehavior
;
/// Defines the vertical direction of a [ButtonBar]'s children if it
/// overflows.
///
/// If the [ButtonBar]'s children do not fit into a single row, then they
/// are arranged in a column. The first action is at the top of the
/// column if this property is set to [VerticalDirection.down], since it
/// "starts" at the top and "ends" at the bottom. On the other hand,
/// the first action will be at the bottom of the column if this
/// property is set to [VerticalDirection.up], since it "starts" at the
/// bottom and "ends" at the top.
final
VerticalDirection
overflowDirection
;
/// Creates a copy of this object but with the given fields replaced with the
/// new values.
ButtonBarThemeData
copyWith
({
...
...
@@ -108,6 +121,7 @@ class ButtonBarThemeData extends Diagnosticable {
EdgeInsetsGeometry
buttonPadding
,
bool
buttonAlignedDropdown
,
ButtonBarLayoutBehavior
layoutBehavior
,
VerticalDirection
overflowDirection
,
})
{
return
ButtonBarThemeData
(
alignment:
alignment
??
this
.
alignment
,
...
...
@@ -118,6 +132,7 @@ class ButtonBarThemeData extends Diagnosticable {
buttonPadding:
buttonPadding
??
this
.
buttonPadding
,
buttonAlignedDropdown:
buttonAlignedDropdown
??
this
.
buttonAlignedDropdown
,
layoutBehavior:
layoutBehavior
??
this
.
layoutBehavior
,
overflowDirection:
overflowDirection
??
this
.
overflowDirection
,
);
}
...
...
@@ -139,6 +154,7 @@ class ButtonBarThemeData extends Diagnosticable {
buttonPadding:
EdgeInsetsGeometry
.
lerp
(
a
?.
buttonPadding
,
b
?.
buttonPadding
,
t
),
buttonAlignedDropdown:
t
<
0.5
?
a
.
buttonAlignedDropdown
:
b
.
buttonAlignedDropdown
,
layoutBehavior:
t
<
0.5
?
a
.
layoutBehavior
:
b
.
layoutBehavior
,
overflowDirection:
t
<
0.5
?
a
.
overflowDirection
:
b
.
overflowDirection
,
);
}
...
...
@@ -153,6 +169,7 @@ class ButtonBarThemeData extends Diagnosticable {
buttonPadding
,
buttonAlignedDropdown
,
layoutBehavior
,
overflowDirection
,
);
}
...
...
@@ -170,7 +187,8 @@ class ButtonBarThemeData extends Diagnosticable {
&&
other
.
buttonHeight
==
buttonHeight
&&
other
.
buttonPadding
==
buttonPadding
&&
other
.
buttonAlignedDropdown
==
buttonAlignedDropdown
&&
other
.
layoutBehavior
==
layoutBehavior
;
&&
other
.
layoutBehavior
==
layoutBehavior
&&
other
.
overflowDirection
==
overflowDirection
;
}
@override
...
...
@@ -188,6 +206,7 @@ class ButtonBarThemeData extends Diagnosticable {
ifTrue:
'dropdown width matches button'
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
ButtonBarLayoutBehavior
>(
'layoutBehavior'
,
layoutBehavior
,
defaultValue:
null
));
properties
.
add
(
DiagnosticsProperty
<
VerticalDirection
>(
'overflowDirection'
,
overflowDirection
,
defaultValue:
null
));
}
}
...
...
packages/flutter/lib/src/material/dialog.dart
View file @
01742673
...
...
@@ -222,6 +222,7 @@ class AlertDialog extends StatelessWidget {
this
.
contentTextStyle
,
this
.
actions
,
this
.
actionsPadding
=
EdgeInsets
.
zero
,
this
.
actionsOverflowDirection
,
this
.
buttonPadding
,
this
.
backgroundColor
,
this
.
elevation
,
...
...
@@ -315,8 +316,32 @@ class AlertDialog extends StatelessWidget {
/// )
/// ```
/// {@end-tool}
///
/// See also:
///
/// * [ButtonBar], which [actions] configures to lay itself out.
final
EdgeInsetsGeometry
actionsPadding
;
/// The vertical direction of [actions] if the children overflow
/// horizontally.
///
/// If the dialog's [actions] do not fit into a single row, then they
/// are arranged in a column. The first action is at the top of the
/// column if this property is set to [VerticalDirection.down], since it
/// "starts" at the top and "ends" at the bottom. On the other hand,
/// the first action will be at the bottom of the column if this
/// property is set to [VerticalDirection.up], since it "starts" at the
/// bottom and "ends" at the top.
///
/// If null then it will use the surrounding
/// [ButtonBarTheme.overflowDirection]. If that is null, it will
/// default to [VerticalDirection.down].
///
/// See also:
///
/// * [ButtonBar], which [actions] configures to lay itself out.
final
VerticalDirection
actionsOverflowDirection
;
/// The padding that surrounds each button in [actions].
///
/// This is different from [actionsPadding], which defines the padding
...
...
@@ -325,6 +350,10 @@ class AlertDialog extends StatelessWidget {
/// If this property is null, then it will use the surrounding
/// [ButtonBarTheme.buttonPadding]. If that is null, it will default to
/// 8.0 logical pixels on the left and right.
///
/// See also:
///
/// * [ButtonBar], which [actions] configures to lay itself out.
final
EdgeInsetsGeometry
buttonPadding
;
/// {@macro flutter.material.dialog.backgroundColor}
...
...
@@ -415,6 +444,7 @@ class AlertDialog extends StatelessWidget {
padding:
actionsPadding
,
child:
ButtonBar
(
buttonPadding:
buttonPadding
,
overflowDirection:
actionsOverflowDirection
,
children:
actions
,
),
);
...
...
packages/flutter/test/material/button_bar_test.dart
View file @
01742673
...
...
@@ -544,5 +544,34 @@ void main() {
expect
(
containerOneRect
.
left
,
buttonBarRect
.
left
);
},
);
testWidgets
(
"ButtonBar's children respects verticalDirection when overflowing"
,
(
WidgetTester
tester
)
async
{
final
Key
keyOne
=
UniqueKey
();
final
Key
keyTwo
=
UniqueKey
();
await
tester
.
pumpWidget
(
MaterialApp
(
home:
ButtonBar
(
alignment:
MainAxisAlignment
.
center
,
// Set padding to zero to align buttons with edge of button bar.
buttonPadding:
EdgeInsets
.
zero
,
// Set the vertical direction to start from the bottom and lay
// out upwards.
overflowDirection:
VerticalDirection
.
up
,
children:
<
Widget
>[
Container
(
key:
keyOne
,
height:
50.0
,
width:
500.0
),
Container
(
key:
keyTwo
,
height:
50.0
,
width:
500.0
),
],
),
),
);
final
Rect
containerOneRect
=
tester
.
getRect
(
find
.
byKey
(
keyOne
));
final
Rect
containerTwoRect
=
tester
.
getRect
(
find
.
byKey
(
keyTwo
));
// Second [Container] should appear above first container.
expect
(
containerTwoRect
.
bottom
,
containerOneRect
.
top
);
},
);
});
}
packages/flutter/test/material/button_bar_theme_test.dart
View file @
01742673
...
...
@@ -18,6 +18,7 @@ void main() {
expect
(
buttonBarTheme
.
buttonPadding
,
null
);
expect
(
buttonBarTheme
.
buttonAlignedDropdown
,
null
);
expect
(
buttonBarTheme
.
layoutBehavior
,
null
);
expect
(
buttonBarTheme
.
overflowDirection
,
null
);
});
test
(
'ThemeData uses default ButtonBarThemeData'
,
()
{
...
...
@@ -39,6 +40,7 @@ void main() {
buttonPadding:
EdgeInsets
.
symmetric
(
vertical:
5.0
),
buttonAlignedDropdown:
false
,
layoutBehavior:
ButtonBarLayoutBehavior
.
padded
,
overflowDirection:
VerticalDirection
.
down
,
);
const
ButtonBarThemeData
barThemeAccent
=
ButtonBarThemeData
(
alignment:
MainAxisAlignment
.
center
,
...
...
@@ -49,6 +51,7 @@ void main() {
buttonPadding:
EdgeInsets
.
symmetric
(
horizontal:
10.0
),
buttonAlignedDropdown:
true
,
layoutBehavior:
ButtonBarLayoutBehavior
.
constrained
,
overflowDirection:
VerticalDirection
.
up
,
);
final
ButtonBarThemeData
lerp
=
ButtonBarThemeData
.
lerp
(
barThemePrimary
,
barThemeAccent
,
0.5
);
...
...
@@ -60,6 +63,7 @@ void main() {
expect
(
lerp
.
buttonPadding
,
equals
(
const
EdgeInsets
.
fromLTRB
(
5.0
,
2.5
,
5.0
,
2.5
)));
expect
(
lerp
.
buttonAlignedDropdown
,
isTrue
);
expect
(
lerp
.
layoutBehavior
,
equals
(
ButtonBarLayoutBehavior
.
constrained
));
expect
(
lerp
.
overflowDirection
,
equals
(
VerticalDirection
.
up
));
});
testWidgets
(
'Default ButtonBarThemeData debugFillProperties'
,
(
WidgetTester
tester
)
async
{
...
...
@@ -85,6 +89,7 @@ void main() {
buttonPadding:
EdgeInsets
.
symmetric
(
horizontal:
7.3
),
buttonAlignedDropdown:
true
,
layoutBehavior:
ButtonBarLayoutBehavior
.
constrained
,
overflowDirection:
VerticalDirection
.
up
,
).
debugFillProperties
(
builder
);
final
List
<
String
>
description
=
builder
.
properties
...
...
@@ -101,6 +106,7 @@ void main() {
'padding: EdgeInsets(7.3, 0.0, 7.3, 0.0)'
,
'dropdown width matches button'
,
'layoutBehavior: ButtonBarLayoutBehavior.constrained'
,
'overflowDirection: VerticalDirection.up'
,
]);
});
...
...
packages/flutter/test/material/dialog_test.dart
View file @
01742673
...
...
@@ -531,6 +531,41 @@ void main() {
);
// right
});
testWidgets
(
'Dialogs can set the vertical direction of actions'
,
(
WidgetTester
tester
)
async
{
final
GlobalKey
key1
=
GlobalKey
();
final
GlobalKey
key2
=
GlobalKey
();
final
AlertDialog
dialog
=
AlertDialog
(
title:
const
Text
(
'title'
),
content:
const
Text
(
'content'
),
actions:
<
Widget
>[
RaisedButton
(
key:
key1
,
onPressed:
()
{},
child:
const
Text
(
'Looooooooooooooong button 1'
),
),
RaisedButton
(
key:
key2
,
onPressed:
()
{},
child:
const
Text
(
'Looooooooooooooong button 2'
),
),
],
actionsOverflowDirection:
VerticalDirection
.
up
,
);
await
tester
.
pumpWidget
(
_appWithAlertDialog
(
tester
,
dialog
),
);
await
tester
.
tap
(
find
.
text
(
'X'
));
await
tester
.
pumpAndSettle
();
final
Rect
buttonOneRect
=
tester
.
getRect
(
find
.
byKey
(
key1
));
final
Rect
buttonTwoRect
=
tester
.
getRect
(
find
.
byKey
(
key2
));
// Second [RaisedButton] should appear above the first.
expect
(
buttonTwoRect
.
bottom
,
buttonOneRect
.
top
);
});
testWidgets
(
'Dialogs removes MediaQuery padding and view insets'
,
(
WidgetTester
tester
)
async
{
BuildContext
outerContext
;
BuildContext
routeContext
;
...
...
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