I'm trying to resize the view of a SearchAnchor to its content. Let's say I have some basic code (taken from here): https://api.flutter.dev/flutter/material/SearchAnchor-class.html. I don't know how many suggestions I'll have to display before hand (I first need to make an API call).
import 'package:flutter/material.dart';
/// Flutter code sample for [SearchAnchor].
const Duration fakeAPIDuration = Duration(seconds: 1);
void main() => runApp(const SearchAnchorAsyncExampleApp());
class SearchAnchorAsyncExampleApp extends StatelessWidget {
const SearchAnchorAsyncExampleApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('SearchAnchor - async'),
),
body: const Center(
child: _AsyncSearchAnchor(),
),
),
);
}
}
class _AsyncSearchAnchor extends StatefulWidget {
const _AsyncSearchAnchor();
@override
State<_AsyncSearchAnchor> createState() => _AsyncSearchAnchorState();
}
class _AsyncSearchAnchorState extends State<_AsyncSearchAnchor> {
// The query currently being searched for. If null, there is no pending
// request.
String? _searchingWithQuery;
// The most recent options received from the API.
late Iterable<Widget> _lastOptions = <Widget>[];
@override
Widget build(BuildContext context) {
return SearchAnchor(
builder: (BuildContext context, SearchController controller) {
return IconButton(
icon: const Icon(Icons.search),
onPressed: () {
controller.openView();
},
);
}, suggestionsBuilder:
(BuildContext context, SearchController controller) async {
_searchingWithQuery = controller.text;
final List<String> options =
(await _FakeAPI.search(_searchingWithQuery!)).toList();
// If another search happened after this one, throw away these options.
// Use the previous options instead and wait for the newer request to
// finish.
if (_searchingWithQuery != controller.text) {
return _lastOptions;
}
_lastOptions = List<ListTile>.generate(options.length, (int index) {
final String item = options[index];
return ListTile(
title: Text(item),
);
});
return _lastOptions;
});
}
}
// Mimics a remote API.
class _FakeAPI {
static const List<String> _kOptions = <String>[
'aardvark',
'bobcat',
'chameleon',
];
// Searches the options, but injects a fake "network" delay.
static Future<Iterable<String>> search(String query) async {
await Future<void>.delayed(fakeAPIDuration); // Fake 1 second delay.
if (query == '') {
return const Iterable<String>.empty();
}
return _kOptions.where((String option) {
return option.contains(query.toLowerCase());
});
}
}
The code above runs, but the suggestions list is way too big. Even after filling up the list of suggestions, it's showing too much empty space. I would like to display a shorter (and empty) suggestion list at the beginning, and after the first API call, I would like the list to resize to its content.
Do you have any idea how to do that?


Not very dynamic, but one can cap the height. It seems that the view height is clambed by the
SearchAnchor'sviewConstraints.Example usage
Probably not the cleanest way to achive dynamic height but you could also use a multiple of the length of
_lastOptionsfor themaxHeight. E.g.maxHeight: kToolbarHeight * _lastOptions.length,