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
4c6929d4
Unverified
Commit
4c6929d4
authored
Apr 19, 2023
by
Qun Cheng
Committed by
GitHub
Apr 19, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Dismiss the docked search view when the window size is changed (#125071)
parent
44738995
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
98 additions
and
38 deletions
+98
-38
search_anchor.dart
packages/flutter/lib/src/material/search_anchor.dart
+20
-38
search_anchor_test.dart
packages/flutter/test/material/search_anchor_test.dart
+78
-0
No files found.
packages/flutter/lib/src/material/search_anchor.dart
View file @
4c6929d4
...
@@ -67,6 +67,11 @@ typedef ViewBuilder = Widget Function(Iterable<Widget> suggestions);
...
@@ -67,6 +67,11 @@ typedef ViewBuilder = Widget Function(Iterable<Widget> suggestions);
/// If [builder] returns an Icon, or any un-tappable widgets, we don't have
/// If [builder] returns an Icon, or any un-tappable widgets, we don't have
/// to explicitly call [SearchController.openView].
/// to explicitly call [SearchController.openView].
///
///
/// The search view route will be popped if the window size is changed and the
/// search view route is not in full-screen mode. However, if the search view route
/// is in full-screen mode, changing the window size, such as rotating a mobile
/// device from portrait mode to landscape mode, will not close the search view.
///
/// {@tool dartpad}
/// {@tool dartpad}
/// This example shows how to use an IconButton to open a search view in a [SearchAnchor].
/// This example shows how to use an IconButton to open a search view in a [SearchAnchor].
/// It also shows how to use [SearchController] to open or close the search view route.
/// It also shows how to use [SearchController] to open or close the search view route.
...
@@ -286,6 +291,7 @@ class SearchAnchor extends StatefulWidget {
...
@@ -286,6 +291,7 @@ class SearchAnchor extends StatefulWidget {
}
}
class
_SearchAnchorState
extends
State
<
SearchAnchor
>
{
class
_SearchAnchorState
extends
State
<
SearchAnchor
>
{
Size
?
_screenSize
;
bool
_anchorIsVisible
=
true
;
bool
_anchorIsVisible
=
true
;
final
GlobalKey
_anchorKey
=
GlobalKey
();
final
GlobalKey
_anchorKey
=
GlobalKey
();
bool
get
_viewIsOpen
=>
!
_anchorIsVisible
;
bool
get
_viewIsOpen
=>
!
_anchorIsVisible
;
...
@@ -301,6 +307,18 @@ class _SearchAnchorState extends State<SearchAnchor> {
...
@@ -301,6 +307,18 @@ class _SearchAnchorState extends State<SearchAnchor> {
_searchController
.
_attach
(
this
);
_searchController
.
_attach
(
this
);
}
}
@override
void
didChangeDependencies
()
{
super
.
didChangeDependencies
();
final
Size
updatedScreenSize
=
MediaQuery
.
of
(
context
).
size
;
if
(
_screenSize
!=
null
&&
_screenSize
!=
updatedScreenSize
)
{
if
(
_searchController
.
isOpen
&&
!
getShowFullScreenView
())
{
_closeView
(
null
);
}
}
_screenSize
=
updatedScreenSize
;
}
@override
@override
void
dispose
()
{
void
dispose
()
{
super
.
dispose
();
super
.
dispose
();
...
@@ -672,45 +690,9 @@ class _ViewContentState extends State<_ViewContent> {
...
@@ -672,45 +690,9 @@ class _ViewContentState extends State<_ViewContent> {
result
=
widget
.
suggestionsBuilder
(
context
,
_controller
);
result
=
widget
.
suggestionsBuilder
(
context
,
_controller
);
final
Size
updatedScreenSize
=
MediaQuery
.
of
(
context
).
size
;
final
Size
updatedScreenSize
=
MediaQuery
.
of
(
context
).
size
;
if
(
_screenSize
!=
updatedScreenSize
)
{
if
(
_screenSize
!=
updatedScreenSize
&&
widget
.
showFullScreenView
)
{
_screenSize
=
updatedScreenSize
;
_screenSize
=
updatedScreenSize
;
setState
(()
{
_viewRect
=
Offset
.
zero
&
_screenSize
!;
final
Rect
anchorRect
=
widget
.
getRect
()
??
_viewRect
;
final
BoxConstraints
constraints
=
widget
.
viewConstraints
??
widget
.
viewTheme
.
constraints
??
widget
.
viewDefaults
.
constraints
!;
final
double
viewWidth
=
clampDouble
(
anchorRect
.
width
,
constraints
.
minWidth
,
constraints
.
maxWidth
);
final
double
viewHeight
=
clampDouble
(
_screenSize
!.
height
*
2
/
3
,
constraints
.
minHeight
,
constraints
.
maxHeight
);
final
Size
updatedViewSize
=
Size
(
viewWidth
,
viewHeight
);
switch
(
Directionality
.
of
(
context
))
{
case
TextDirection
.
ltr
:
final
double
viewLeftToScreenRight
=
_screenSize
!.
width
-
anchorRect
.
left
;
final
double
viewTopToScreenBottom
=
_screenSize
!.
height
-
anchorRect
.
top
;
// Make sure the search view doesn't go off the screen when the screen
// size is changed. If the search view doesn't fit, move the top-left
// corner of the view to fit the window. If the window is smaller than
// the view, then we resize the view to fit the window.
Offset
topLeft
=
anchorRect
.
topLeft
;
if
(
viewLeftToScreenRight
<
viewWidth
)
{
topLeft
=
Offset
(
_screenSize
!.
width
-
math
.
min
(
viewWidth
,
_screenSize
!.
width
),
anchorRect
.
top
);
}
if
(
viewTopToScreenBottom
<
viewHeight
)
{
topLeft
=
Offset
(
topLeft
.
dx
,
_screenSize
!.
height
-
math
.
min
(
viewHeight
,
_screenSize
!.
height
));
}
_viewRect
=
topLeft
&
updatedViewSize
;
return
;
case
TextDirection
.
rtl
:
final
double
viewTopToScreenBottom
=
_screenSize
!.
height
-
anchorRect
.
top
;
Offset
topLeft
=
Offset
(
math
.
max
(
anchorRect
.
right
-
viewWidth
,
0.0
),
anchorRect
.
top
,
);
if
(
viewTopToScreenBottom
<
viewHeight
)
{
topLeft
=
Offset
(
topLeft
.
dx
,
_screenSize
!.
height
-
math
.
min
(
viewHeight
,
_screenSize
!.
height
));
}
_viewRect
=
topLeft
&
updatedViewSize
;
}
});
}
}
}
}
...
...
packages/flutter/test/material/search_anchor_test.dart
View file @
4c6929d4
...
@@ -1560,6 +1560,84 @@ void main() {
...
@@ -1560,6 +1560,84 @@ void main() {
final
Rect
searchViewRectRTL
=
tester
.
getRect
(
find
.
descendant
(
of:
findViewContent
(),
matching:
find
.
byType
(
SizedBox
)).
first
);
final
Rect
searchViewRectRTL
=
tester
.
getRect
(
find
.
descendant
(
of:
findViewContent
(),
matching:
find
.
byType
(
SizedBox
)).
first
);
expect
(
searchViewRectRTL
,
equals
(
const
Rect
.
fromLTRB
(
0.0
,
0.0
,
200.0
,
200.0
)));
expect
(
searchViewRectRTL
,
equals
(
const
Rect
.
fromLTRB
(
0.0
,
0.0
,
200.0
,
200.0
)));
});
});
testWidgets
(
'Docked search view route is popped if the window size changes'
,
(
WidgetTester
tester
)
async
{
addTearDown
(
tester
.
view
.
reset
);
tester
.
view
.
physicalSize
=
const
Size
(
500.0
,
600.0
);
tester
.
view
.
devicePixelRatio
=
1.0
;
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Material
(
child:
SearchAnchor
(
isFullScreen:
false
,
builder:
(
BuildContext
context
,
SearchController
controller
)
{
return
Align
(
alignment:
Alignment
.
bottomRight
,
child:
IconButton
(
icon:
const
Icon
(
Icons
.
search
),
onPressed:
()
{
controller
.
openView
();
},
),
);
},
suggestionsBuilder:
(
BuildContext
context
,
SearchController
controller
)
{
return
<
Widget
>[];
},
),
),
));
// Open the search view
await
tester
.
tap
(
find
.
byIcon
(
Icons
.
search
));
await
tester
.
pumpAndSettle
();
expect
(
find
.
byIcon
(
Icons
.
arrow_back
),
findsOneWidget
);
// Change window size
tester
.
view
.
physicalSize
=
const
Size
(
250.0
,
200.0
);
tester
.
view
.
devicePixelRatio
=
1.0
;
await
tester
.
pumpAndSettle
();
expect
(
find
.
byIcon
(
Icons
.
arrow_back
),
findsNothing
);
});
testWidgets
(
'Full-screen search view route should stay if the window size changes'
,
(
WidgetTester
tester
)
async
{
addTearDown
(
tester
.
view
.
reset
);
tester
.
view
.
physicalSize
=
const
Size
(
500.0
,
600.0
);
tester
.
view
.
devicePixelRatio
=
1.0
;
await
tester
.
pumpWidget
(
MaterialApp
(
home:
Material
(
child:
SearchAnchor
(
isFullScreen:
true
,
builder:
(
BuildContext
context
,
SearchController
controller
)
{
return
Align
(
alignment:
Alignment
.
bottomRight
,
child:
IconButton
(
icon:
const
Icon
(
Icons
.
search
),
onPressed:
()
{
controller
.
openView
();
},
),
);
},
suggestionsBuilder:
(
BuildContext
context
,
SearchController
controller
)
{
return
<
Widget
>[];
},
),
),
));
// Open a full-screen search view
await
tester
.
tap
(
find
.
byIcon
(
Icons
.
search
));
await
tester
.
pumpAndSettle
();
expect
(
find
.
byIcon
(
Icons
.
arrow_back
),
findsOneWidget
);
// Change window size
tester
.
view
.
physicalSize
=
const
Size
(
250.0
,
200.0
);
tester
.
view
.
devicePixelRatio
=
1.0
;
await
tester
.
pumpAndSettle
();
expect
(
find
.
byIcon
(
Icons
.
arrow_back
),
findsOneWidget
);
});
}
}
TextStyle
?
_iconStyle
(
WidgetTester
tester
,
IconData
icon
)
{
TextStyle
?
_iconStyle
(
WidgetTester
tester
,
IconData
icon
)
{
...
...
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