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
751f119c
Unverified
Commit
751f119c
authored
Feb 25, 2019
by
Hans Muller
Committed by
GitHub
Feb 25, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Ensure that the DropdownButton menu respects its parents bounds (#28371)
parent
fc6079a2
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
101 additions
and
11 deletions
+101
-11
dropdown.dart
packages/flutter/lib/src/material/dropdown.dart
+56
-11
dropdown_test.dart
packages/flutter/test/material/dropdown_test.dart
+45
-0
No files found.
packages/flutter/lib/src/material/dropdown.dart
View file @
751f119c
...
@@ -327,19 +327,67 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
...
@@ -327,19 +327,67 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
@override
@override
Widget
buildPage
(
BuildContext
context
,
Animation
<
double
>
animation
,
Animation
<
double
>
secondaryAnimation
)
{
Widget
buildPage
(
BuildContext
context
,
Animation
<
double
>
animation
,
Animation
<
double
>
secondaryAnimation
)
{
return
LayoutBuilder
(
builder:
(
BuildContext
context
,
BoxConstraints
constraints
)
{
return
_DropdownRoutePage
<
T
>(
route:
this
,
constraints:
constraints
,
items:
items
,
padding:
padding
,
buttonRect:
buttonRect
,
selectedIndex:
selectedIndex
,
elevation:
elevation
,
theme:
theme
,
style:
style
,
);
}
);
}
void
_dismiss
()
{
navigator
?.
removeRoute
(
this
);
}
}
class
_DropdownRoutePage
<
T
>
extends
StatelessWidget
{
const
_DropdownRoutePage
({
Key
key
,
this
.
route
,
this
.
constraints
,
this
.
items
,
this
.
padding
,
this
.
buttonRect
,
this
.
selectedIndex
,
this
.
elevation
=
8
,
this
.
theme
,
this
.
style
,
})
:
super
(
key:
key
);
final
_DropdownRoute
<
T
>
route
;
final
BoxConstraints
constraints
;
final
List
<
DropdownMenuItem
<
T
>>
items
;
final
EdgeInsetsGeometry
padding
;
final
Rect
buttonRect
;
final
int
selectedIndex
;
final
int
elevation
;
final
ThemeData
theme
;
final
TextStyle
style
;
@override
Widget
build
(
BuildContext
context
)
{
assert
(
debugCheckHasDirectionality
(
context
));
assert
(
debugCheckHasDirectionality
(
context
));
final
double
screenHeight
=
MediaQuery
.
of
(
context
).
size
.
h
eight
;
final
double
availableHeight
=
constraints
.
maxH
eight
;
final
double
maxMenuHeight
=
screen
Height
-
2.0
*
_kMenuItemHeight
;
final
double
maxMenuHeight
=
available
Height
-
2.0
*
_kMenuItemHeight
;
final
double
buttonTop
=
buttonRect
.
top
;
final
double
buttonTop
=
buttonRect
.
top
;
final
double
buttonBottom
=
buttonRect
.
bottom
;
final
double
buttonBottom
=
math
.
min
(
buttonRect
.
bottom
,
availableHeight
)
;
// If the button is placed on the bottom or top of the screen, its top or
// If the button is placed on the bottom or top of the screen, its top or
// bottom may be less than [_kMenuItemHeight] from the edge of the screen.
// bottom may be less than [_kMenuItemHeight] from the edge of the screen.
// In this case, we want to change the menu limits to align with the top
// In this case, we want to change the menu limits to align with the top
// or bottom edge of the button.
// or bottom edge of the button.
final
double
topLimit
=
math
.
min
(
_kMenuItemHeight
,
buttonTop
);
final
double
topLimit
=
math
.
min
(
_kMenuItemHeight
,
buttonTop
);
final
double
bottomLimit
=
math
.
max
(
screen
Height
-
_kMenuItemHeight
,
buttonBottom
);
final
double
bottomLimit
=
math
.
max
(
available
Height
-
_kMenuItemHeight
,
buttonBottom
);
final
double
selectedItemOffset
=
selectedIndex
*
_kMenuItemHeight
+
kMaterialListPadding
.
top
;
final
double
selectedItemOffset
=
selectedIndex
*
_kMenuItemHeight
+
kMaterialListPadding
.
top
;
...
@@ -359,24 +407,25 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
...
@@ -359,24 +407,25 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
// respectively.
// respectively.
if
(
menuTop
<
topLimit
)
if
(
menuTop
<
topLimit
)
menuTop
=
math
.
min
(
buttonTop
,
topLimit
);
menuTop
=
math
.
min
(
buttonTop
,
topLimit
);
if
(
menuBottom
>
bottomLimit
)
{
if
(
menuBottom
>
bottomLimit
)
{
menuBottom
=
math
.
max
(
buttonBottom
,
bottomLimit
);
menuBottom
=
math
.
max
(
buttonBottom
,
bottomLimit
);
menuTop
=
menuBottom
-
menuHeight
;
menuTop
=
menuBottom
-
menuHeight
;
}
}
if
(
scrollController
==
null
)
{
if
(
route
.
scrollController
==
null
)
{
// The limit is asymmetrical because we do not care how far positive the
// The limit is asymmetrical because we do not care how far positive the
// limit goes. We are only concerned about the case where the value of
// limit goes. We are only concerned about the case where the value of
// [buttonTop - menuTop] is larger than selectedItemOffset, ie. when
// [buttonTop - menuTop] is larger than selectedItemOffset, ie. when
// the button is close to the bottom of the screen and the selected item
// the button is close to the bottom of the screen and the selected item
// is close to 0.
// is close to 0.
final
double
scrollOffset
=
preferredMenuHeight
>
maxMenuHeight
?
math
.
max
(
0.0
,
selectedItemOffset
-
(
buttonTop
-
menuTop
))
:
0.0
;
final
double
scrollOffset
=
preferredMenuHeight
>
maxMenuHeight
?
math
.
max
(
0.0
,
selectedItemOffset
-
(
buttonTop
-
menuTop
))
:
0.0
;
scrollController
=
ScrollController
(
initialScrollOffset:
scrollOffset
);
route
.
scrollController
=
ScrollController
(
initialScrollOffset:
scrollOffset
);
}
}
final
TextDirection
textDirection
=
Directionality
.
of
(
context
);
final
TextDirection
textDirection
=
Directionality
.
of
(
context
);
Widget
menu
=
_DropdownMenu
<
T
>(
Widget
menu
=
_DropdownMenu
<
T
>(
route:
this
,
route:
route
,
padding:
padding
.
resolve
(
textDirection
),
padding:
padding
.
resolve
(
textDirection
),
);
);
...
@@ -404,10 +453,6 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
...
@@ -404,10 +453,6 @@ class _DropdownRoute<T> extends PopupRoute<_DropdownRouteResult<T>> {
),
),
);
);
}
}
void
_dismiss
()
{
navigator
?.
removeRoute
(
this
);
}
}
}
/// An item in a menu created by a [DropdownButton].
/// An item in a menu created by a [DropdownButton].
...
...
packages/flutter/test/material/dropdown_test.dart
View file @
751f119c
...
@@ -1035,4 +1035,49 @@ void main() {
...
@@ -1035,4 +1035,49 @@ void main() {
await
tester
.
pumpAndSettle
();
await
tester
.
pumpAndSettle
();
expect
(
getMenuScroll
(),
4312.0
);
expect
(
getMenuScroll
(),
4312.0
);
});
});
testWidgets
(
'Dropdown menu respects parent size limits'
,
(
WidgetTester
tester
)
async
{
// Regression test for https://github.com/flutter/flutter/issues/24417
int
selectedIndex
;
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Scaffold
(
bottomNavigationBar:
const
SizedBox
(
height:
200
),
body:
Navigator
(
onGenerateRoute:
(
RouteSettings
settings
)
{
return
MaterialPageRoute
<
void
>(
builder:
(
BuildContext
context
)
{
return
SafeArea
(
child:
Container
(
alignment:
Alignment
.
topLeft
,
// From material/dropdown.dart (menus are unaligned by default):
// _kUnalignedMenuMargin = EdgeInsetsDirectional.only(start: 16.0, end: 24.0)
// This padding ensures that the entire menu will be visible
padding:
const
EdgeInsetsDirectional
.
only
(
start:
16.0
,
end:
24.0
),
child:
DropdownButton
<
int
>(
value:
12
,
onChanged:
(
int
i
)
{
selectedIndex
=
i
;
},
items:
List
<
DropdownMenuItem
<
int
>>.
generate
(
100
,
(
int
i
)
{
return
DropdownMenuItem
<
int
>(
value:
i
,
child:
Text
(
'
$i
'
));
}),
),
),
);
},
);
},
),
),
),
);
await
tester
.
tap
(
find
.
text
(
'12'
));
await
tester
.
pumpAndSettle
();
expect
(
selectedIndex
,
null
);
await
tester
.
tap
(
find
.
text
(
'13'
).
last
);
await
tester
.
pumpAndSettle
();
expect
(
selectedIndex
,
13
);
});
}
}
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