Search code examples
flutterflutter-layoutbottom-sheetgesture-recognitionflutter-showmodalbottomsheet

Is it possible to enable tap outside the bottomsheet?


I want to enable users to take actions outside the bottom sheet as well. For example in the image shown below, I want the user to make a tap on the play button. I cannot do that now since the barrier of the bottomsheet is blocking the click to the play button.

enter image description here

  • From my research, the bottom sheet is a full-screen component. It appears to be of height half screen is a deception. (By making barrier color transparent and adding height constraints).
showModalBottomSheet(
      context: context,
      isDismissible: false,
      barrierColor: Colors.transparent,
      builder: (_) {
        return GestureDetector(
          behavior: HitTestBehavior.translucent,
          child: Container(
            constraints: BoxConstraints(maxHeight: height),
            color: Theme.of(context).cardColor,
            child: child.....
          ),
        );
      },
      isScrollControlled: true,
    );

Solution

  • I solved it like bottom sheet but with a different method. I hope I got the question right.

    example gif

    import 'package:flutter/material.dart';
    class BottomSheetOutside extends StatefulWidget {
      @override
      _BottomSheetOutsideState createState() => _BottomSheetOutsideState();
    }
    
    class _BottomSheetOutsideState extends State<BottomSheetOutside> with SingleTickerProviderStateMixin {
      AnimationController _controller;
      Animation<Offset> offset;
    
      @override
      void initState() {
        super.initState();
        _controller = AnimationController(vsync: this, duration: Duration(seconds: 1));
        offset = Tween<Offset>(begin: Offset(0.0, 1.0), end: Offset.zero).animate(_controller);
      }
    
      @override
      void dispose() {
        super.dispose();
        _controller.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            children: [
              Expanded(flex: 4, child: buildTop),
              Expanded(flex: 6, child: buildBottom),
            ],
          ),
        );
      }
    
      Container get buildTop {
        return Container(
          width: double.infinity,
          color: Colors.red,
          child: IconButton(
            icon: Icon(Icons.play_circle_fill_rounded),
            onPressed: () {
              switch (_controller.status) {
                case AnimationStatus.dismissed:
                  _controller.forward();
                  break;
                case AnimationStatus.forward:
                  break;
                case AnimationStatus.reverse:
                  break;
                case AnimationStatus.completed:
                  _controller.reverse();
                  break;
              }
            },
          ),
        );
      }
    
      Stack get buildBottom {
        return Stack(children: [
          Container(color: Colors.blue),
          buildBottomSlide,
        ]);
      }
    
      Widget get buildBottomSlide {
        return SlideTransition(
          position: offset,
          child: Card(
            child: ListView.builder(
              itemCount: 10,
              itemBuilder: (context, index) => ListTile(
                leading: Icon(Icons.comment),
                title: Text("Test $index"),
              ),
            ),
          ),
        );
      }
    }