Add constraint options to SearchAnchor suggestions builder (#148856)

Refactors the `SearchAnchor` suggestions builder to not take up the whole screen

https://github.com/flutter/flutter/issues/148852
This commit is contained in:
Rexios
2024-11-13 20:19:09 -05:00
committed by GitHub
parent dec763979c
commit cc6ee0cc32
5 changed files with 212 additions and 84 deletions

View File

@@ -50,6 +50,9 @@ class _${blockName}DefaultsM3 extends ${blockName}ThemeData {
@override
EdgeInsetsGeometry? get barPadding => const EdgeInsets.symmetric(horizontal: 8.0);
@override
bool get shrinkWrap => false;
@override
Color? get dividerColor => ${componentColor('md.comp.search-view.divider')};
}

View File

@@ -6,6 +6,7 @@ import 'dart:async';
import 'dart:math' as math;
import 'dart:ui';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'adaptive_text_selection_toolbar.dart';
@@ -133,6 +134,7 @@ class SearchAnchor extends StatefulWidget {
this.dividerColor,
this.viewConstraints,
this.viewPadding,
this.shrinkWrap,
this.textCapitalization,
this.viewOnChanged,
this.viewOnSubmitted,
@@ -170,6 +172,7 @@ class SearchAnchor extends StatefulWidget {
EdgeInsetsGeometry? viewBarPadding,
MaterialStateProperty<TextStyle?>? barTextStyle,
MaterialStateProperty<TextStyle?>? barHintStyle,
ViewBuilder? viewBuilder,
Widget? viewLeading,
Iterable<Widget>? viewTrailing,
String? viewHintText,
@@ -184,6 +187,7 @@ class SearchAnchor extends StatefulWidget {
BoxConstraints? constraints,
BoxConstraints? viewConstraints,
EdgeInsetsGeometry? viewPadding,
bool? shrinkWrap,
bool? isFullScreen,
SearchController searchController,
TextCapitalization textCapitalization,
@@ -328,6 +332,14 @@ class SearchAnchor extends StatefulWidget {
/// If null, the value of [SearchViewThemeData.padding] will be used.
final EdgeInsetsGeometry? viewPadding;
/// Whether the search view should shrink-wrap its contents.
///
/// Has no effect if the search view is full-screen.
///
/// If null, the value of [SearchViewThemeData.shrinkWrap] will be used. If
/// this is also null, then the default value is `false`.
final bool? shrinkWrap;
/// {@macro flutter.widgets.editableText.textCapitalization}
final TextCapitalization? textCapitalization;
@@ -454,6 +466,7 @@ class _SearchAnchorState extends State<SearchAnchor> {
dividerColor: widget.dividerColor,
viewConstraints: widget.viewConstraints,
viewPadding: widget.viewPadding,
shrinkWrap: widget.shrinkWrap,
showFullScreenView: getShowFullScreenView(),
toggleVisibility: toggleVisibility,
textDirection: Directionality.of(context),
@@ -536,6 +549,7 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> {
this.dividerColor,
this.viewConstraints,
this.viewPadding,
this.shrinkWrap,
this.textCapitalization,
required this.showFullScreenView,
required this.anchorKey,
@@ -566,6 +580,7 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> {
final Color? dividerColor;
final BoxConstraints? viewConstraints;
final EdgeInsetsGeometry? viewPadding;
final bool? shrinkWrap;
final TextCapitalization? textCapitalization;
final bool showFullScreenView;
final GlobalKey anchorKey;
@@ -690,7 +705,6 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> {
@override
Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
return Directionality(
textDirection: textDirection ?? TextDirection.ltr,
child: AnimatedBuilder(
@@ -732,7 +746,9 @@ class _SearchViewRoute extends PopupRoute<_SearchViewRoute> {
viewHeaderTextStyle: viewHeaderTextStyle,
viewHeaderHintStyle: viewHeaderHintStyle,
dividerColor: dividerColor,
viewConstraints: viewConstraints,
viewPadding: viewPadding,
shrinkWrap: shrinkWrap,
showFullScreenView: showFullScreenView,
animation: curvedAnimation!,
topPadding: topPadding,
@@ -774,7 +790,9 @@ class _ViewContent extends StatefulWidget {
this.viewHeaderTextStyle,
this.viewHeaderHintStyle,
this.dividerColor,
this.viewConstraints,
this.viewPadding,
this.shrinkWrap,
this.textCapitalization,
required this.showFullScreenView,
required this.topPadding,
@@ -803,7 +821,9 @@ class _ViewContent extends StatefulWidget {
final TextStyle? viewHeaderTextStyle;
final TextStyle? viewHeaderHintStyle;
final Color? dividerColor;
final BoxConstraints? viewConstraints;
final EdgeInsetsGeometry? viewPadding;
final bool? shrinkWrap;
final TextCapitalization? textCapitalization;
final bool showFullScreenView;
final double topPadding;
@@ -911,19 +931,6 @@ class _ViewContentState extends State<_ViewContent> {
viewListFadeOnIntervalCurve.dispose();
}
Widget viewBuilder(Iterable<Widget> suggestions) {
if (widget.viewBuilder == null) {
return MediaQuery.removePadding(
context: context,
removeTop: true,
child: ListView(
children: suggestions.toList()
),
);
}
return widget.viewBuilder!(suggestions);
}
Future<void> updateSuggestions() async {
if (searchValue != _controller.text) {
searchValue = _controller.text;
@@ -998,6 +1005,16 @@ class _ViewContentState extends State<_ViewContent> {
?? viewTheme.barPadding
?? viewDefaults.barPadding;
final BoxConstraints effectiveConstraints = widget.viewConstraints
?? viewTheme.constraints
?? viewDefaults.constraints!;
final double minWidth = math.min(effectiveConstraints.minWidth, _viewRect.width);
final double minHeight = math.min(effectiveConstraints.minHeight, _viewRect.height);
final bool effectiveShrinkWrap = widget.shrinkWrap
?? viewTheme.shrinkWrap
?? viewDefaults.shrinkWrap!;
final Widget viewDivider = DividerTheme(
data: dividerTheme.copyWith(color: effectiveDividerColor),
child: const Divider(height: 1),
@@ -1007,9 +1024,13 @@ class _ViewContentState extends State<_ViewContent> {
alignment: Alignment.topLeft,
child: Transform.translate(
offset: _viewRect.topLeft,
child: SizedBox(
width: _viewRect.width,
height: _viewRect.height,
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: minWidth,
maxWidth: _viewRect.width,
minHeight: minHeight,
maxHeight: _viewRect.height,
),
child: Padding(
padding: widget.showFullScreenView ? EdgeInsets.zero : (effectivePadding ?? EdgeInsets.zero),
child: Material(
@@ -1018,57 +1039,69 @@ class _ViewContentState extends State<_ViewContent> {
color: effectiveBackgroundColor,
surfaceTintColor: effectiveSurfaceTint,
elevation: effectiveElevation,
child: ClipRect(
clipBehavior: Clip.antiAlias,
child: OverflowBox(
alignment: Alignment.topLeft,
maxWidth: math.min(widget.viewMaxWidth, _screenSize!.width),
minWidth: 0,
child: FadeTransition(
opacity: viewIconsFadeCurve,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: widget.topPadding),
child: SafeArea(
top: false,
bottom: false,
child: SearchBar(
autoFocus: true,
constraints: headerConstraints ?? (widget.showFullScreenView ? BoxConstraints(minHeight: _SearchViewDefaultsM3.fullScreenBarHeight) : null),
padding: WidgetStatePropertyAll<EdgeInsetsGeometry?>(effectiveBarPadding),
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: (String value) {
widget.viewOnChanged?.call(value);
updateSuggestions();
},
onSubmitted: widget.viewOnSubmitted,
textCapitalization: widget.textCapitalization,
textInputAction: widget.textInputAction,
keyboardType: widget.keyboardType,
),
child: OverflowBox(
alignment: Alignment.topLeft,
maxWidth: math.min(widget.viewMaxWidth, _screenSize!.width),
minWidth: 0,
fit: OverflowBoxFit.deferToChild,
child: FadeTransition(
opacity: viewIconsFadeCurve,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: widget.topPadding),
child: SafeArea(
top: false,
bottom: false,
child: SearchBar(
autoFocus: true,
constraints: headerConstraints ?? (widget.showFullScreenView ? BoxConstraints(minHeight: _SearchViewDefaultsM3.fullScreenBarHeight) : null),
padding: WidgetStatePropertyAll<EdgeInsetsGeometry?>(effectiveBarPadding),
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: (String value) {
widget.viewOnChanged?.call(value);
updateSuggestions();
},
onSubmitted: widget.viewOnSubmitted,
textCapitalization: widget.textCapitalization,
textInputAction: widget.textInputAction,
keyboardType: widget.keyboardType,
),
),
),
if (!effectiveShrinkWrap || minHeight > 0 || widget.showFullScreenView || result.isNotEmpty) ...<Widget>[
FadeTransition(
opacity: viewDividerFadeCurve,
child: viewDivider),
Expanded(
child: viewDivider,
),
Flexible(
fit: (effectiveShrinkWrap && !widget.showFullScreenView) ? FlexFit.loose : FlexFit.tight,
child: FadeTransition(
opacity: viewListFadeOnIntervalCurve,
child: viewBuilder(result),
child: widget.viewBuilder == null
? MediaQuery.removePadding(
context: context,
removeTop: true,
child: ListView(
shrinkWrap: effectiveShrinkWrap,
children: result.toList(),
),
)
: widget.viewBuilder!(result),
),
),
],
),
],
),
),
),
@@ -1095,6 +1128,7 @@ class _SearchAnchorWithSearchBar extends SearchAnchor {
super.viewBarPadding,
MaterialStateProperty<TextStyle?>? barTextStyle,
MaterialStateProperty<TextStyle?>? barHintStyle,
super.viewBuilder,
super.viewLeading,
super.viewTrailing,
String? viewHintText,
@@ -1109,6 +1143,7 @@ class _SearchAnchorWithSearchBar extends SearchAnchor {
BoxConstraints? constraints,
super.viewConstraints,
super.viewPadding,
super.shrinkWrap,
super.isFullScreen,
super.searchController,
super.textCapitalization,
@@ -1716,6 +1751,9 @@ class _SearchViewDefaultsM3 extends SearchViewThemeData {
@override
EdgeInsetsGeometry? get barPadding => const EdgeInsets.symmetric(horizontal: 8.0);
@override
bool get shrinkWrap => false;
@override
Color? get dividerColor => _colors.outline;
}

View File

@@ -46,6 +46,7 @@ class SearchViewThemeData with Diagnosticable {
this.constraints,
this.padding,
this.barPadding,
this.shrinkWrap,
this.side,
this.shape,
this.headerHeight,
@@ -87,6 +88,9 @@ class SearchViewThemeData with Diagnosticable {
/// Overrides the value of the padding for [SearchAnchor.viewBarPadding]
final EdgeInsetsGeometry? barPadding;
/// Overrides the value of the shrink wrap for [SearchAnchor.shrinkWrap].
final bool? shrinkWrap;
/// Overrides the value of the divider color for [SearchAnchor.dividerColor].
final Color? dividerColor;
@@ -104,6 +108,7 @@ class SearchViewThemeData with Diagnosticable {
BoxConstraints? constraints,
EdgeInsetsGeometry? padding,
EdgeInsetsGeometry? barPadding,
bool? shrinkWrap,
Color? dividerColor,
}) {
return SearchViewThemeData(
@@ -118,6 +123,7 @@ class SearchViewThemeData with Diagnosticable {
constraints: constraints ?? this.constraints,
padding: padding ?? this.padding,
barPadding: barPadding ?? this.barPadding,
shrinkWrap: shrinkWrap ?? this.shrinkWrap,
dividerColor: dividerColor ?? this.dividerColor,
);
}
@@ -139,6 +145,7 @@ class SearchViewThemeData with Diagnosticable {
constraints: BoxConstraints.lerp(a?.constraints, b?.constraints, t),
padding: EdgeInsetsGeometry.lerp(a?.padding, b?.padding, t),
barPadding: EdgeInsetsGeometry.lerp(a?.barPadding, b?.barPadding, t),
shrinkWrap: t < 0.5 ? a?.shrinkWrap : b?.shrinkWrap,
dividerColor: Color.lerp(a?.dividerColor, b?.dividerColor, t),
);
}
@@ -156,6 +163,7 @@ class SearchViewThemeData with Diagnosticable {
constraints,
padding,
barPadding,
shrinkWrap,
dividerColor,
);
@@ -179,6 +187,7 @@ class SearchViewThemeData with Diagnosticable {
&& other.constraints == constraints
&& other.padding == padding
&& other.barPadding == barPadding
&& other.shrinkWrap == shrinkWrap
&& other.dividerColor == dividerColor;
}
@@ -196,6 +205,7 @@ class SearchViewThemeData with Diagnosticable {
properties.add(DiagnosticsProperty<BoxConstraints>('constraints', constraints, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry?>('padding', padding, defaultValue: null));
properties.add(DiagnosticsProperty<EdgeInsetsGeometry?>('barPadding', barPadding, defaultValue: null));
properties.add(DiagnosticsProperty<bool?>('shrinkWrap', shrinkWrap, defaultValue: null));
properties.add(DiagnosticsProperty<Color?>('dividerColor', dividerColor, defaultValue: null));
}

View File

@@ -1188,9 +1188,9 @@ void main() {
await tester.pumpWidget(buildSearchAnchor(platform));
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();
final SizedBox sizedBox = tester.widget<SizedBox>(find.descendant(of: findViewContent(), matching: find.byType(SizedBox)).first);
expect(sizedBox.width, 800.0);
expect(sizedBox.height, 600.0);
final Size size = tester.getSize(find.descendant(of: findViewContent(), matching: find.byType(ConstrainedBox)).first);
expect(size.width, 800.0);
expect(size.height, 600.0);
}
for (final TargetPlatform platform in <TargetPlatform>[ TargetPlatform.linux, TargetPlatform.windows ]) {
@@ -1198,9 +1198,9 @@ void main() {
await tester.pumpWidget(buildSearchAnchor(platform));
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();
final SizedBox sizedBox = tester.widget<SizedBox>(find.descendant(of: findViewContent(), matching: find.byType(SizedBox)).first);
expect(sizedBox.width, 360.0);
expect(sizedBox.height, 400.0);
final Size size = tester.getSize(find.descendant(of: findViewContent(), matching: find.byType(ConstrainedBox)).first);
expect(size.width, 360.0);
expect(size.height, 400.0);
}
});
@@ -1234,9 +1234,9 @@ void main() {
await tester.pumpWidget(buildSearchAnchor(platform));
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();
final SizedBox sizedBox = tester.widget<SizedBox>(find.descendant(of: findViewContent(), matching: find.byType(SizedBox)).first);
expect(sizedBox.width, 800.0);
expect(sizedBox.height, 600.0);
final Size size = tester.getSize(find.descendant(of: findViewContent(), matching: find.byType(ConstrainedBox)).first);
expect(size.width, 800.0);
expect(size.height, 600.0);
}
});
@@ -1378,7 +1378,7 @@ void main() {
await tester.pumpWidget(Container());
await tester.pumpWidget(buildAnchor(viewBuilder: (Iterable<Widget> suggestions)
=> GridView.count(crossAxisCount: 5, children: suggestions.toList(),)
=> GridView.count(crossAxisCount: 5, children: suggestions.toList())
));
await tester.tap(find.widgetWithIcon(IconButton, Icons.search));
await tester.pumpAndSettle();
@@ -1386,6 +1386,36 @@ void main() {
expect(find.byType(GridView), findsOneWidget);
});
testWidgets('SearchAnchor.bar respects viewBuilder property', (WidgetTester tester) async {
Widget buildAnchor({ViewBuilder? viewBuilder}) {
return MaterialApp(
home: Material(
child: SearchAnchor.bar(
viewBuilder: viewBuilder,
suggestionsBuilder: (BuildContext context, SearchController controller) {
return <Widget>[];
},
),
),
);
}
await tester.pumpWidget(buildAnchor());
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();
// Default is a ListView.
expect(find.byType(ListView), findsOneWidget);
await tester.pumpWidget(Container());
await tester.pumpWidget(buildAnchor(viewBuilder: (Iterable<Widget> suggestions)
=> GridView.count(crossAxisCount: 5, children: suggestions.toList())
));
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();
expect(find.byType(ListView), findsNothing);
expect(find.byType(GridView), findsOneWidget);
});
testWidgets('SearchAnchor respects viewLeading property', (WidgetTester tester) async {
Widget buildAnchor({Widget? viewLeading}) {
return MaterialApp(
@@ -1692,6 +1722,49 @@ void main() {
expect(padding.padding, EdgeInsets.zero);
});
testWidgets('SearchAnchor respects shrinkWrap property', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: Material(
child: SearchAnchor(
isFullScreen: false,
shrinkWrap: true,
viewConstraints: const BoxConstraints(),
builder: (BuildContext context, SearchController controller) {
return IconButton(icon: const Icon(Icons.search), onPressed: () {
controller.openView();
},);
},
suggestionsBuilder: (BuildContext context, SearchController controller) {
return List<Widget>.generate(
controller.text.length,
(int index) => ListTile(title: Text('Item $index')),
);
}
),
),
));
await tester.tap(find.widgetWithIcon(IconButton, Icons.search));
await tester.pumpAndSettle();
final Finder findDivider = find.descendant(of: findViewContent(), matching: find.byType(Divider));
// Divider should not be shown if there are no suggestions
expect(findDivider, findsNothing);
final Finder findMaterial = find.descendant(of: findViewContent(), matching: find.byType(Material)).first;
final Rect materialRectWithoutSuggestions = tester.getRect(findMaterial);
expect(materialRectWithoutSuggestions, equals(const Rect.fromLTRB(0.0, 0.0, 800.0, 56.0)));
await tester.enterText(find.byType(SearchBar), 'a');
await tester.pumpAndSettle();
expect(findDivider, findsOneWidget);
final Rect materialRectWithSuggestions = tester.getRect(findMaterial);
expect(materialRectWithSuggestions, equals(const Rect.fromLTRB(0.0, 0.0, 800.0, 113.0)));
});
testWidgets('SearchAnchor respects dividerColor property', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: Material(
@@ -1741,9 +1814,9 @@ void main() {
await tester.tap(find.widgetWithIcon(IconButton, Icons.search));
await tester.pumpAndSettle();
final SizedBox sizedBox = tester.widget<SizedBox>(find.descendant(of: findViewContent(), matching: find.byType(SizedBox)).first);
expect(sizedBox.width, 280.0);
expect(sizedBox.height, 390.0);
final Size size = tester.getSize(find.descendant(of: findViewContent(), matching: find.byType(ConstrainedBox)).first);
expect(size.width, 280.0);
expect(size.height, 390.0);
});
testWidgets('SearchAnchor respects viewBarPadding property', (WidgetTester tester) async {
@@ -1802,7 +1875,7 @@ void main() {
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(SizedBox)).first);
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(ConstrainedBox)).first);
expect(searchViewRect, equals(const Rect.fromLTRB(388.0, 0.0, 748.0, 400.0)));
// Search view top left should be the same as the anchor top left
@@ -1839,7 +1912,7 @@ void main() {
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(SizedBox)).first);
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(ConstrainedBox)).first);
expect(searchViewRect, equals(const Rect.fromLTRB(52.0, 0.0, 412.0, 400.0)));
// Search view top right should be the same as the anchor top right
@@ -2049,7 +2122,7 @@ void main() {
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(SizedBox)).first);
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(ConstrainedBox)).first);
expect(searchViewRect, equals(const Rect.fromLTRB(0.0, 0.0, 800.0, 400.0)));
// Search view has same width with the default anchor(search bar).
@@ -2128,7 +2201,7 @@ void main() {
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(SizedBox)).first);
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(ConstrainedBox)).first);
expect(searchViewRect, equals(const Rect.fromLTRB(440.0, 200.0, 800.0, 600.0)));
});
@@ -2169,7 +2242,7 @@ void main() {
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(SizedBox)).first);
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(ConstrainedBox)).first);
expect(searchViewRect, equals(const Rect.fromLTRB(0.0, 200.0, 360.0, 600.0)));
});
@@ -2216,7 +2289,7 @@ void main() {
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(SizedBox)).first);
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(ConstrainedBox)).first);
expect(searchViewRect, equals(const Rect.fromLTRB(0.0, 0.0, 200.0, 200.0)));
// Test RTL text direction.
@@ -2231,7 +2304,7 @@ void main() {
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();
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(ConstrainedBox)).first);
expect(searchViewRectRTL, equals(const Rect.fromLTRB(0.0, 0.0, 200.0, 200.0)));
});
@@ -2394,7 +2467,7 @@ void main() {
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(SizedBox)).first);
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(ConstrainedBox)).first);
expect(searchViewRect.topLeft, equals(const Offset(rootSpacing, rootSpacing)));
});
@@ -2440,7 +2513,7 @@ void main() {
await tester.tap(find.byIcon(Icons.search));
await tester.pumpAndSettle();
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(SizedBox)).first);
final Rect searchViewRect = tester.getRect(find.descendant(of: findViewContent(), matching: find.byType(ConstrainedBox)).first);
expect(searchViewRect.bottomRight, equals(const Offset(300.0, 300.0)));
});

View File

@@ -33,6 +33,7 @@ void main() {
expect(themeData.headerHintStyle, null);
expect(themeData.padding, null);
expect(themeData.barPadding, null);
expect(themeData.shrinkWrap, null);
expect(themeData.dividerColor, null);
const SearchViewTheme theme = SearchViewTheme(data: SearchViewThemeData(), child: SizedBox());
@@ -47,6 +48,7 @@ void main() {
expect(theme.data.headerHintStyle, null);
expect(themeData.padding, null);
expect(themeData.barPadding, null);
expect(themeData.shrinkWrap, null);
expect(theme.data.dividerColor, null);
});
@@ -77,6 +79,7 @@ void main() {
constraints: BoxConstraints(minWidth: 350, minHeight: 240),
padding: EdgeInsets.only(bottom: 32.0),
barPadding: EdgeInsets.zero,
shrinkWrap: true,
).debugFillProperties(builder);
final List<String> description = builder.properties
@@ -95,6 +98,7 @@ void main() {
expect(description[8], 'constraints: BoxConstraints(350.0<=w<=Infinity, 240.0<=h<=Infinity)');
expect(description[9], 'padding: EdgeInsets(0.0, 0.0, 0.0, 32.0)');
expect(description[10], 'barPadding: EdgeInsets.zero');
expect(description[11], 'shrinkWrap: true');
});
group('[Theme, SearchViewTheme, SearchView properties overrides]', () {
@@ -196,9 +200,9 @@ void main() {
expect(material.surfaceTintColor, surfaceTintColor);
expect(material.shape, shape);
final SizedBox sizedBox = tester.widget<SizedBox>(find.descendant(of: findViewContent(), matching: find.byType(SizedBox)).first);
expect(sizedBox.width, 250.0);
expect(sizedBox.height, 450.0);
final Size size = tester.getSize(find.descendant(of: findViewContent(), matching: find.byType(ConstrainedBox)).first);
expect(size.width, 250.0);
expect(size.height, 450.0);
final Text hintText = tester.widget(find.text('hint text'));
expect(hintText.style?.color, headerHintStyle.color);