1

On my flutter_map I have an IconButton which it should cause a SearchBar to appear only when clicked. When search is done, the SearchBar can go into hiding again and only said icon be visible.

I have implemented this by the code attached at the end.

However I have a problem: the width of the SearchBar is inherited, I guess, from its parent. But the parent is said IconButton which I would prefer it to occupy only the space needed by its icon image. Well, this creates a mess becayse the width of the child SearchBar is now 30px!

The workaround I found does not seem ideal to me: force said IconButton to occupy the full screen width so that its child SearchBar occupies the same width. This full-width is not visible (only the icon is visible). The side effect is that the whole column of the buttons are now moved into the center, as expected, despite a left-alignment. Because now there is this one button with some huge width in that Column.

Container(
  alignment: Alignment.topLeft,
  // uncomment following to show the problem:
  width: MediaQuery.sizeOf(context).width,
  child: IconButton(
    icon: const Icon(Icons.search),
    onPressed: () {
      // opens the SearchBar:
      // can I tell it to resize?
      controller.openView();
    },

  )
)

Does anyone know a more elegant way to click on an icon and get the search bar to open in full-width?

Here is code which demonstrates the problem. By uncommenting a line preceded by (THIS FIXES) you will see how the search bar has the correct width but the column of buttons is pushed to the center.

(the whole code opens in a popup and incorporates a flutter_map as well as the buttons, so I need the structure below more-or-less)

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(title: 'Flutter Demo', home: const MyHomePage());
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Align(
        alignment: Alignment.topLeft,
        // Center is a layout widget. It takes a single child and positions it
        // in the middle of the parent.
        child: MyMapButtonsWidget(),
      ),
    );
  }
}

class MySearchWidget extends StatefulWidget {
  const MySearchWidget({super.key});

  @override
  State<MySearchWidget> createState() => _MySearchWidgetState();
}

class _MySearchWidgetState extends State<MySearchWidget> {
  final _searchController = SearchController();

  @override
  Widget build(BuildContext context) {
    return SearchAnchor(
      dividerColor: Colors.red,
      // this refers to the history/results list dropdown
      isFullScreen: false,
      viewConstraints: BoxConstraints(
        maxHeight: MediaQuery.sizeOf(context).height * 0.75,
      ),
      viewBackgroundColor: Colors.grey.shade200,
      keyboardType: TextInputType.streetAddress,
      viewShape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(10),
      ),
      searchController: _searchController,

      builder: (BuildContext context, SearchController controller) {
        // Here I click on this IconButton in order to open the SearchBar
        // but its size is inherited from the IconButton and it is not full-width!
        return Container(
          // THIS FIXES the problem, but I don' want the icon to
          // "occupy" this wide space!!!
          /*  width: MediaQuery
              .sizeOf(context)
              .width * 1.0,
              */
          child: IconButton(
            icon: const Icon(Icons.search),
            onPressed: () {
              controller.openView();
            },
          ),
        );
        /*
        // This works fine
       return SearchBar(
              shape: WidgetStateProperty.all(
                RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(8.0),
                ),
              ),
              controller: controller,
              padding: const WidgetStatePropertyAll<EdgeInsets>(
                EdgeInsets.symmetric(horizontal: 16.0),
              ),
              onTap: () {
                controller.openView();
              },
              // add as many icons at the end
              trailing: <Widget>[
                IconButton(
                  onPressed: controller.clear,
                  icon: const Icon(Icons.close),
                ),
              ],
              // add the search icon at the front
              leading: const Icon(Icons.search),
            );
            */
      },
      suggestionsBuilder:
          (BuildContext context, SearchController controller) async {
            return [Text("aaa")];
          },
    );
  }
}

class MyMapButtonsWidget extends StatefulWidget {
  const MyMapButtonsWidget({super.key});

  @override
  State<MyMapButtonsWidget> createState() => _MyMapButtonsWidgetState();
}

class _MyMapButtonsWidgetState extends State<MyMapButtonsWidget> {
  @override
  Widget build(BuildContext context) {
    return Material(
      child: Column(
        children: [
          Column(
            mainAxisSize: MainAxisSize.min,
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              Container(
                height: 35,
                padding: EdgeInsets.only(left: 5),
                child: MySearchWidget(),
              ),
              // zoom-in
              Container(
                width: 35,
                height: 35,
                padding: EdgeInsets.only(left: 5),
                child: FloatingActionButton(
                  onPressed: () {
                    print("zoomin");
                  },
                  child: Icon(
                    Icons.add_circle_outlined,
                    size: 25,
                    color: Colors.black,
                  ),
                ),
              ),
              const SizedBox(height: 8),
              // zoom-out
              Container(
                width: 35,
                height: 35,
                padding: EdgeInsets.only(left: 5),
                child: FloatingActionButton(
                  onPressed: () {
                    print("zoomout");
                  },
                  child: Icon(
                    Icons.remove_circle_outline,
                    size: 25,
                    color: Colors.black,
                  ),
                ),
              ),
              const SizedBox(height: 8),
              // pinpoint my geo-location
              Container(
                width: 35,
                height: 35,
                padding: EdgeInsets.only(left: 5),
                child: FloatingActionButton(
                  onPressed: () {
                    print("currentloc");
                  },
                  child: Icon(
                    Icons.remove_circle_outline,
                    size: 25,
                    color: Colors.black,
                  ),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}
1
  • 1
    So you want the SearchBar to have full width? Commented 14 hours ago

1 Answer 1

1

To have full width on searchView, you can set the constraints as you did for height;

 return SearchAnchor(
      dividerColor: Colors.red,
      isFullScreen: false,
      viewConstraints: BoxConstraints(
        maxHeight: MediaQuery.sizeOf(context).height * 0.75,
        minWidth: MediaQuery.sizeOf(context).width, /// as much  as you want
      ),
Sign up to request clarification or add additional context in comments.

1 Comment

yes that does it nicely! Thank you @Md. Yeasin Sheikh

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.