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
b2550fe5
Unverified
Commit
b2550fe5
authored
Sep 11, 2021
by
xubaolin
Committed by
GitHub
Sep 11, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix a dropdown button menu position bug (#89199)
parent
3a608547
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
39 additions
and
5 deletions
+39
-5
dropdown.dart
packages/flutter/lib/src/material/dropdown.dart
+16
-5
dropdown_test.dart
packages/flutter/test/material/dropdown_test.dart
+23
-0
No files found.
packages/flutter/lib/src/material/dropdown.dart
View file @
b2550fe5
...
...
@@ -517,7 +517,10 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
// selected item is aligned with the button's vertical center, as far as
// that's possible given availableHeight.
_MenuLimits
getMenuLimits
(
Rect
buttonRect
,
double
availableHeight
,
int
index
)
{
final
double
maxMenuHeight
=
availableHeight
-
2.0
*
_kMenuItemHeight
;
double
computedMaxHeight
=
availableHeight
-
2.0
*
_kMenuItemHeight
;
if
(
menuMaxHeight
!=
null
)
{
computedMaxHeight
=
math
.
min
(
computedMaxHeight
,
menuMaxHeight
!);
}
final
double
buttonTop
=
buttonRect
.
top
;
final
double
buttonBottom
=
math
.
min
(
buttonRect
.
bottom
,
availableHeight
);
final
double
selectedItemOffset
=
getItemOffset
(
index
);
...
...
@@ -535,8 +538,8 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
preferredMenuHeight
+=
itemHeights
.
reduce
((
double
total
,
double
height
)
=>
total
+
height
);
// If there are too many elements in the menu, we need to shrink it down
// so it is at most the
maxMenu
Height.
final
double
menuHeight
=
math
.
min
(
maxMenu
Height
,
preferredMenuHeight
);
// so it is at most the
computedMax
Height.
final
double
menuHeight
=
math
.
min
(
computedMax
Height
,
preferredMenuHeight
);
double
menuBottom
=
menuTop
+
menuHeight
;
// If the computed top or bottom of the menu are outside of the range
...
...
@@ -544,14 +547,21 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
// than the button height and the button is at the very bottom or top of the
// screen, the menu will be aligned with the bottom or top of the button
// respectively.
if
(
menuTop
<
topLimit
)
if
(
menuTop
<
topLimit
)
{
menuTop
=
math
.
min
(
buttonTop
,
topLimit
);
menuBottom
=
menuTop
+
menuHeight
;
}
if
(
menuBottom
>
bottomLimit
)
{
menuBottom
=
math
.
max
(
buttonBottom
,
bottomLimit
);
menuTop
=
menuBottom
-
menuHeight
;
}
if
(
menuBottom
-
itemHeights
[
selectedIndex
]
/
2.0
<
buttonBottom
-
buttonRect
.
height
/
2.0
)
{
menuBottom
=
buttonBottom
-
buttonRect
.
height
/
2.0
+
itemHeights
[
selectedIndex
]
/
2.0
;
menuTop
=
menuBottom
-
menuHeight
;
}
double
scrollOffset
=
0
;
// If all of the menu items will not fit within availableHeight then
// compute the scroll offset that will line the selected menu item up
...
...
@@ -559,7 +569,7 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
// shown - subsequently we leave the scroll offset where the user left
// it. This scroll offset is only accurate for fixed height menu items
// (the default).
if
(
preferredMenuHeight
>
maxMenu
Height
)
{
if
(
preferredMenuHeight
>
computedMax
Height
)
{
// The offset should be zero if the selected item is in view at the beginning
// of the menu. Otherwise, the scroll offset should center the item if possible.
scrollOffset
=
math
.
max
(
0.0
,
selectedItemOffset
-
(
buttonTop
-
menuTop
));
...
...
@@ -568,6 +578,7 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
scrollOffset
=
math
.
min
(
scrollOffset
,
preferredMenuHeight
-
menuHeight
);
}
assert
(
menuHeight
==
menuBottom
-
menuTop
);
return
_MenuLimits
(
menuTop
,
menuBottom
,
menuHeight
,
scrollOffset
);
}
}
...
...
packages/flutter/test/material/dropdown_test.dart
View file @
b2550fe5
...
...
@@ -3127,6 +3127,29 @@ void main() {
expect
(
menuHeight
,
defaultMenuHeight
);
});
// Regression test for https://github.com/flutter/flutter/issues/89029
testWidgets
(
'menu position test with `menuMaxHeight`'
,
(
WidgetTester
tester
)
async
{
final
Key
buttonKey
=
UniqueKey
();
await
tester
.
pumpWidget
(
buildFrame
(
buttonKey:
buttonKey
,
value:
'6'
,
items:
List
<
String
>.
generate
(
/*length=*/
64
,
(
int
index
)
=>
index
.
toString
()),
onChanged:
onChanged
,
menuMaxHeight:
2
*
kMinInteractiveDimension
,
));
await
tester
.
tap
(
find
.
text
(
'6'
));
await
tester
.
pumpAndSettle
();
final
RenderBox
menuBox
=
tester
.
renderObject
(
find
.
byType
(
ListView
));
final
RenderBox
buttonBox
=
tester
.
renderObject
(
find
.
byKey
(
buttonKey
));
// The menu's bottom should align with the drop-button's bottom.
expect
(
menuBox
.
localToGlobal
(
menuBox
.
paintBounds
.
bottomCenter
).
dy
,
buttonBox
.
localToGlobal
(
buttonBox
.
paintBounds
.
bottomCenter
).
dy
,
);
});
// Regression test for https://github.com/flutter/flutter/issues/76614
testWidgets
(
'Do not crash if used in very short screen'
,
(
WidgetTester
tester
)
async
{
// The default item height is 48.0 pixels and needs two items padding since
...
...
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