'Need help for a showModalTopSheet

I would like to be able to implement a showModalTopSheet on the booking.com site

On the first image (img1), a search has already been performed. The search criteria are included in an input button. By clicking on this button, I get a more detailed search.(img2)

img1

img2



Solution 1:[1]

Have you tried using stack widget as the parent and making a separate widget for the top search and filter section. And make a Boolean state for the filter. So the state will turn true when a search is made.

So try to use stack as the parent and make the list of hotels as the first child and make the search text box as the second child with container having padding and alignment property as Alignment.topCenter and make the stack fit property as StackFit.loose .

Below is the example code for implementing the above suggestion.

Link for the sample working images and video.

https://drive.google.com/drive/folders/1BrEtcQCg8VEN7WQgXUorBc34R04gipAA?usp=sharing

import 'package:flutter/material.dart';

class SampleWidget extends StatefulWidget {
  const SampleWidget({Key? key}) : super(key: key);

  @override
  State<SampleWidget> createState() => _SampleWidgetState();
}

class _SampleWidgetState extends State<SampleWidget>
    with TickerProviderStateMixin {
  late TabController _tabController;
  bool _isFilterEnabled = false;

  @override
  void initState() {
    _tabController = new TabController(length: 3, vsync: this, initialIndex: 0);
    super.initState();
  }

  TabBar getTabBar() {
    return TabBar(
      indicatorColor: Colors.white,
      controller: _tabController,
      tabs: [
        Container(
          padding: EdgeInsets.only(top: 20),
          height: 65,
          child: Tab(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: const [
                Icon(
                  Icons.import_export,
                  color: Colors.grey,
                ),
                Text(
                  "Trier",
                  style: TextStyle(
                    color: Colors.grey,
                  ),
                ),
              ],
            ),
          ),
        ),
        Container(
          padding: const EdgeInsets.only(top: 20),
          height: 50,
          child: Tab(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: const [
                Icon(
                  Icons.tune,
                  color: Colors.grey,
                ),
                Text(
                  "Filter",
                  style: TextStyle(
                    color: Colors.grey,
                  ),
                ),
              ],
            ),
          ),
        ),
        Container(
          padding: const EdgeInsets.only(top: 20),
          height: 50,
          child: Tab(
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: const [
                Icon(
                  Icons.map,
                  color: Colors.grey,
                ),
                Text(
                  "Carte",
                  style: TextStyle(
                    color: Colors.grey,
                  ),
                ),
              ],
            ),
          ),
        ),
      ],
    );
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        Scaffold(
          appBar: AppBar(
            automaticallyImplyLeading: false,
            backgroundColor: const Color(0xFF013580),
            bottom: PreferredSize(
              preferredSize: getTabBar().preferredSize,
              child: ColoredBox(
                color: Colors.white,
                child: getTabBar(),
              ),
            ),
          ),
          body: TabBarView(
            controller: _tabController,
            children: [
              ListView.builder(
                itemBuilder: (index, context) => const ListTile(
                  leading: Icon(Icons.abc),
                ),
                itemCount: 20,
              ),
              ListView.builder(
                itemBuilder: (index, context) => const ListTile(
                  leading: Icon(Icons.access_alarm),
                ),
                itemCount: 20,
              ),
              ListView.builder(
                itemBuilder: (index, context) => const ListTile(
                  leading: Icon(Icons.ac_unit),
                ),
                itemCount: 20,
              )
            ],
          ),
        ),
        Material(
          color: Colors.transparent,
          child: InkWell(
            splashColor: Colors.transparent,
            onTap: () {
              print("container is pressed");
              setState(() {
                _isFilterEnabled = !_isFilterEnabled;
              });
            },
            child: Container(
              height: 60,
              child: Row(
                children: const [
                  Icon(
                    Icons.chevron_left,
                    color: Colors.grey,
                  ),
                  SizedBox(width: 20),
                  Text(
                    "Sample Text text",
                    style: TextStyle(
                      color: Colors.grey,
                      fontSize: 18,
                      decoration: TextDecoration.none,
                    ),
                  )
                ],
              ),
              margin: const EdgeInsets.only(
                  left: 20, right: 20, bottom: 20, top: 5),
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.circular(5),
                border: Border.all(color: Colors.amber, width: 4),
              ),
            ),
          ),
        ),
        if (_isFilterEnabled)
          Material(
            elevation: 5,
            color: Colors.transparent,
            child: Container(
              color: Colors.white,
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: [
                  const SizedBox(height: 10),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                    children: [
                      InkWell(
                        onTap: () {
                          setState(() {
                            _isFilterEnabled = !_isFilterEnabled;
                          });
                        },
                        child: Icon(
                          Icons.close,
                        ),
                      ),
                      Text(
                        "Modifiez Votre recherche",
                        style: TextStyle(
                            color: Colors.black,
                            fontSize: 20,
                            decoration: TextDecoration.none,
                            fontWeight: FontWeight.w600),
                      )
                    ],
                  ),
                  const SizedBox(height: 10),
                  Container(
                    margin: EdgeInsets.all(10),
                    decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(5),
                      border: Border.all(color: Colors.amber, width: 4),
                    ),
                    child: Column(
                      children: [
                        Container(
                          padding: const EdgeInsets.only(
                            top: 8,
                            bottom: 5,
                          ),
                          child: Row(
                            children: const [
                              SizedBox(width: 10),
                              Icon(Icons.search),
                              SizedBox(width: 10),
                              Text("France")
                            ],
                          ),
                        ),
                        const Divider(color: Colors.black38),
                        Container(
                          padding: const EdgeInsets.only(
                            top: 8,
                            bottom: 5,
                          ),
                          child: Row(
                            children: const [
                              SizedBox(width: 10),
                              Icon(Icons.search),
                              SizedBox(width: 10),
                              Text("France")
                            ],
                          ),
                        ),
                        const Divider(color: Colors.black38),
                        Container(
                          padding: const EdgeInsets.only(
                            top: 8,
                            bottom: 8,
                          ),
                          child: Row(
                            children: const [
                              SizedBox(width: 10),
                              Icon(Icons.search),
                              SizedBox(width: 10),
                              Text("France")
                            ],
                          ),
                        ),
                        Container(
                          color: Color(0xFF0171c2),
                          height: 50,
                          width: double.infinity,
                          child: const Center(
                            child: Text(
                              " Recharge",
                              style: TextStyle(
                                color: Colors.white,
                                fontSize: 18,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                          ),
                        )
                      ],
                    ),
                  ),
                  const SizedBox(height: 10),
                ],
              ),
            ),
          )
      ],
    );
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1