Skip to content

Commit

Permalink
Clip search view content during animation (#126975)
Browse files Browse the repository at this point in the history
Fixes #126590

This PR is to clip the view content when the view size is not big enough, such as during animation.
Also removes some unused properties in `_ViewContent` class: `getRect` and `viewConstraints`
  • Loading branch information
QuncCccccc authored May 18, 2023
1 parent 8089a30 commit f31dae2
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 55 deletions.
117 changes: 62 additions & 55 deletions packages/flutter/lib/src/material/search_anchor.dart
Original file line number Diff line number Diff line change
Expand Up @@ -579,11 +579,10 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> {
viewHeaderTextStyle: viewHeaderTextStyle,
viewHeaderHintStyle: viewHeaderHintStyle,
dividerColor: dividerColor,
viewConstraints: viewConstraints,
showFullScreenView: showFullScreenView,
animation: curvedAnimation,
getRect: getRect,
topPadding: topPadding,
viewMaxWidth: _rectTween.end!.width,
viewRect: viewRect,
viewDefaults: viewDefaults,
viewTheme: viewTheme,
Expand Down Expand Up @@ -616,11 +615,10 @@ class _ViewContent extends StatefulWidget {
this.viewHeaderTextStyle,
this.viewHeaderHintStyle,
this.dividerColor,
this.viewConstraints,
required this.showFullScreenView,
required this.getRect,
required this.topPadding,
required this.animation,
required this.viewMaxWidth,
required this.viewRect,
required this.viewDefaults,
required this.viewTheme,
Expand All @@ -641,11 +639,10 @@ class _ViewContent extends StatefulWidget {
final TextStyle? viewHeaderTextStyle;
final TextStyle? viewHeaderHintStyle;
final Color? dividerColor;
final BoxConstraints? viewConstraints;
final bool showFullScreenView;
final ValueGetter<Rect?> getRect;
final double topPadding;
final Animation<double> animation;
final double viewMaxWidth;
final Rect viewRect;
final SearchViewThemeData viewDefaults;
final SearchViewThemeData viewTheme;
Expand Down Expand Up @@ -690,9 +687,11 @@ class _ViewContentState extends State<_ViewContent> {
result = widget.suggestionsBuilder(context, _controller);
final Size updatedScreenSize = MediaQuery.of(context).size;

if (_screenSize != updatedScreenSize && widget.showFullScreenView) {
if (_screenSize != updatedScreenSize) {
_screenSize = updatedScreenSize;
_viewRect = Offset.zero & _screenSize!;
if (widget.showFullScreenView) {
_viewRect = Offset.zero & _screenSize!;
}
}
}

Expand Down Expand Up @@ -782,56 +781,64 @@ class _ViewContentState extends State<_ViewContent> {
color: effectiveBackgroundColor,
surfaceTintColor: effectiveSurfaceTint,
elevation: effectiveElevation,
child: FadeTransition(
opacity: CurvedAnimation(
parent: widget.animation,
curve: _kViewIconsFadeOnInterval,
reverseCurve: _kViewIconsFadeOnInterval.flipped,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: widget.topPadding),
child: SafeArea(
top: false,
bottom: false,
child: SearchBar(
constraints: widget.showFullScreenView ? BoxConstraints(minHeight: _SearchViewDefaultsM3.fullScreenBarHeight) : null,
focusNode: _focusNode,
leading: widget.viewLeading ?? defaultLeading,
trailing: widget.viewTrailing ?? defaultTrailing,
hintText: widget.viewHintText,
backgroundColor: const MaterialStatePropertyAll<Color>(Colors.transparent),
overlayColor: const MaterialStatePropertyAll<Color>(Colors.transparent),
elevation: const MaterialStatePropertyAll<double>(0.0),
textStyle: MaterialStatePropertyAll<TextStyle?>(effectiveTextStyle),
hintStyle: MaterialStatePropertyAll<TextStyle?>(effectiveHintStyle),
controller: _controller,
onChanged: (_) {
updateSuggestions();
},
),
),
child: ClipRect(
clipBehavior: Clip.antiAlias,
child: OverflowBox(
alignment: Alignment.topLeft,
maxWidth: math.min(widget.viewMaxWidth, _screenSize!.width),
minWidth: 0,
child: FadeTransition(
opacity: CurvedAnimation(
parent: widget.animation,
curve: _kViewIconsFadeOnInterval,
reverseCurve: _kViewIconsFadeOnInterval.flipped,
),
FadeTransition(
opacity: CurvedAnimation(
parent: widget.animation,
curve: _kViewDividerFadeOnInterval,
reverseCurve: _kViewFadeOnInterval.flipped,
),
child: viewDivider),
Expanded(
child: FadeTransition(
opacity: CurvedAnimation(
parent: widget.animation,
curve: _kViewListFadeOnInterval,
reverseCurve: _kViewListFadeOnInterval.flipped,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: widget.topPadding),
child: SafeArea(
top: false,
bottom: false,
child: SearchBar(
constraints: widget.showFullScreenView ? BoxConstraints(minHeight: _SearchViewDefaultsM3.fullScreenBarHeight) : null,
focusNode: _focusNode,
leading: widget.viewLeading ?? defaultLeading,
trailing: widget.viewTrailing ?? defaultTrailing,
hintText: widget.viewHintText,
backgroundColor: const MaterialStatePropertyAll<Color>(Colors.transparent),
overlayColor: const MaterialStatePropertyAll<Color>(Colors.transparent),
elevation: const MaterialStatePropertyAll<double>(0.0),
textStyle: MaterialStatePropertyAll<TextStyle?>(effectiveTextStyle),
hintStyle: MaterialStatePropertyAll<TextStyle?>(effectiveHintStyle),
controller: _controller,
onChanged: (_) {
updateSuggestions();
},
),
),
),
child: viewBuilder(result),
),
FadeTransition(
opacity: CurvedAnimation(
parent: widget.animation,
curve: _kViewDividerFadeOnInterval,
reverseCurve: _kViewFadeOnInterval.flipped,
),
child: viewDivider),
Expanded(
child: FadeTransition(
opacity: CurvedAnimation(
parent: widget.animation,
curve: _kViewListFadeOnInterval,
reverseCurve: _kViewListFadeOnInterval.flipped,
),
child: viewBuilder(result),
),
),
],
),
],
),
),
),
),
Expand Down
40 changes: 40 additions & 0 deletions packages/flutter/test/material/search_anchor_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1639,6 +1639,46 @@ void main() {
await tester.pumpAndSettle();
expect(find.byIcon(Icons.arrow_back), findsOneWidget);
});

testWidgets('Search view route does not throw exception during pop animation', (WidgetTester tester) async {
// regression test for https://github.com/flutter/flutter/issues/126590.
await tester.pumpWidget(MaterialApp(
home: Material(
child: Center(
child: SearchAnchor(
builder: (BuildContext context, SearchController controller) {
return IconButton(
icon: const Icon(Icons.search),
onPressed: () {
controller.openView();
},
);
},
suggestionsBuilder: (BuildContext context, SearchController controller) {
return List<Widget>.generate(5, (int index) {
final String item = 'item $index';
return ListTile(
leading: const Icon(Icons.history),
title: Text(item),
trailing: const Icon(Icons.chevron_right),
onTap: () {},
);
});
}),
),
),
));

// Open search view
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();

// Pop search view route
await tester.tap(find.byIcon(Icons.arrow_back));
await tester.pumpAndSettle();

// No exception.
});
}

TextStyle? _iconStyle(WidgetTester tester, IconData icon) {
Expand Down

0 comments on commit f31dae2

Please sign in to comment.