Jay Tillu
Jay Tillu

Reputation: 1548

How to overlap button on BottomSheet in Flutter?

In my design, there is a close button in the BottomSheet. I have tried Stack. But it didn't work. Does anyone know how to achieve the result? Thanks :)

Overlap Button in BottomSheet


modalBottomSheet(context) {
  return showModalBottomSheet(
    context: context,
    builder: (context) {
      return Stack(
        children: [
          Container(
            child: Text('Sample Text'),
          ),
          Container(
            height: 50,
            width: 50,
            decoration: BoxDecoration(
              color: Colors.red,
              shape: BoxShape.circle,
            ),
          ),
        ],
      );
    }
  );
}

Upvotes: 1

Views: 4577

Answers (2)

showModalBottomSheet(
          backgroundColor: Colors.transparent,
          context: context,
          builder: (BuildContext context) {
            return Stack(clipBehavior: Clip.none, children: [
              Container(
                decoration: const BoxDecoration(
                    color: Colors.white,
                    borderRadius:
                        BorderRadius.vertical(top: Radius.circular(20))),
                height: 220.h,
                child: Padding(
                  padding: const EdgeInsets.symmetric(
                      horizontal: 10.0, vertical: 16),
                  child: Center(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: <Widget>[
                         ElevatedButton(
                            color: Colors.green,
                            onPressed: () {},
                            child: const Center(child: Text('Remove')))
                      ],
                    ),
                  ),
                ),
              ),
              Positioned(
                  top: -30.h,
                  right: 12.w,
                  child: FloatingActionButton(
                    onPressed: () {},
                    child: const Icon(Icons.close),
                  )),
            ]);
          },
        )

Upvotes: 0

fravolt
fravolt

Reputation: 3001

So I've been trying around for a bit, and this seems to work as you explained.

  modalBottomSheet(context) {
    return showModalBottomSheet(
        context: context,
        builder: (context) {
          // using a scaffold helps to more easily position the FAB
          return Scaffold(
            body: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                SizedBox(
                  width: double.maxFinite,
                ),
                Padding(
                  padding: EdgeInsets.all(30.0),
                  child: Text("Text in the sheet"),
                ),
              ],
            ),
            // translate the FAB up by 30
            floatingActionButton: Container(
              transform: Matrix4.translationValues(0.0, -30, 0.0),  // translate up by 30
              child: FloatingActionButton(
                onPressed: () {
                  // do stuff
                  print('doing stuff');
                },
                child: Icon(Icons.add),
              ),
            ),
            // dock it to the center top (from which it is translated)
            floatingActionButtonLocation: FloatingActionButtonLocation.centerTop,
          );
        });
  }

The meat of the solution here is to transform the Container which contains the FAB. I got this idea from this older SO answer to a somewhat related question.

The result looks like this:

screenshot

You'll probably have to make some more edits to achieve the exact result you desire, but I hope this sets you on the right path.

Edit

When, in the above solution, you want to press the FAB, and you tap the top half, the onPressed handler fires, but the modal also closes. You should probably use a WillPopScope that only pops when the actual button is pressed (and not the area around/above it). If you think it's fine pressing anywhere above it as well, you can just leave it as-is.

Upvotes: 3

Related Questions