最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

flutter - How to enable interaction with background elements while using DraggableScrollableSheet with showBottomSheet? - Stack

programmeradmin3浏览0评论

I'm using the showBottomSheet method to display a bottom sheet in my Flutter app. However, when I wrap my content inside a DraggableScrollableSheet, it blocks interaction with the rest of the screen.

If I remove DraggableScrollableSheet and use a simple Container, background interaction works as expected. However, I need DraggableScrollableSheet because I rely on its snapSizes and snap animation functionality.

Is there a way to allow interaction with the rest of the screen while still using DraggableScrollableSheet inside showBottomSheet?

Any help or workaround would be greatly appreciated!

Example Code:

void _showBottomSheet(BuildContext context) {
  showBottomSheet(
    context: context,
    backgroundColor: Colors.transparent,
    builder: (context) {
      return DraggableScrollableSheet(
        initialChildSize: 0.5,
        minChildSize: 0.2,
        maxChildSize: 1,
        snap: true,
        snapSizes: [0.2, 0.5, 1.0],
        builder: (context, scrollController) {
          return Container(
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
            ),
            child: ListView.builder(
              controller: scrollController,
              itemCount: 20,
              itemBuilder: (context, index) {
                return ListTile(title: Text("Item $index"));
              },
            ),
          );
        },
      );
    },
  );
}

I'm using the showBottomSheet method to display a bottom sheet in my Flutter app. However, when I wrap my content inside a DraggableScrollableSheet, it blocks interaction with the rest of the screen.

If I remove DraggableScrollableSheet and use a simple Container, background interaction works as expected. However, I need DraggableScrollableSheet because I rely on its snapSizes and snap animation functionality.

Is there a way to allow interaction with the rest of the screen while still using DraggableScrollableSheet inside showBottomSheet?

Any help or workaround would be greatly appreciated!

Example Code:

void _showBottomSheet(BuildContext context) {
  showBottomSheet(
    context: context,
    backgroundColor: Colors.transparent,
    builder: (context) {
      return DraggableScrollableSheet(
        initialChildSize: 0.5,
        minChildSize: 0.2,
        maxChildSize: 1,
        snap: true,
        snapSizes: [0.2, 0.5, 1.0],
        builder: (context, scrollController) {
          return Container(
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
            ),
            child: ListView.builder(
              controller: scrollController,
              itemCount: 20,
              itemBuilder: (context, index) {
                return ListTile(title: Text("Item $index"));
              },
            ),
          );
        },
      );
    },
  );
}
Share Improve this question edited Mar 11 at 6:14 Rehan asked Mar 11 at 5:40 RehanRehan 1821 gold badge1 silver badge12 bronze badges 1
  • You can mimic with Stack – Md. Yeasin Sheikh Commented Mar 11 at 6:24
Add a comment  | 

2 Answers 2

Reset to default 0

In Flutter, when you open a BottomSheet, it typically takes over user interaction, preventing gestures from passing through to the background widgets. However, if you want to keep the background list scrollable while the bottom sheet is open, you can use the showModalBottomSheet with the isScrollControlled: true property and wrap the BottomSheet with a DraggableScrollableSheet. Here's how you can do it:

Using DraggableScrollableSheet

The DraggableScrollableSheet allows the bottom sheet to be partially opened while still allowing interactions with the background list.

Try this and give me feedback that it's Works or Not?

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomeScreen(),
    );
  }
}

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Scrollable List with Bottom Sheet")),
      body: Stack(
        children: [
          // Background ListView
          ListView.builder(
            itemCount: 50,
            itemBuilder: (context, index) {
              return ListTile(
                title: Text('Item $index'),
              );
            },
          ),

          // Draggable Scrollable Bottom Sheet
          DraggableScrollableSheet(
            initialChildSize: 0.3, // How much it takes initially
            minChildSize: 0.1, // Minimum size when collapsed
            maxChildSize: 0.8, // Maximum height
            builder: (context, scrollController) {
              return Container(
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
                  boxShadow: [BoxShadow(color: Colors.black26, blurRadius: 10)],
                ),
                child: ListView.builder(
                  controller: scrollController, // Attach the controller
                  itemCount: 20,
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: Text('Bottom Sheet Item $index'),
                    );
                  },
                ),
              );
            },
          ),
        ],
      ),
    );
  }
}

Use ModalBottomSheetRoute

void _showBottomSheet(BuildContext context) {
  showModalBottomSheet(
    context: context,
    backgroundColor: Colors.transparent,
    isDismissible: false, 
    enableDrag: false, 
    isScrollControlled: true, 
    builder: (context) {
      return DraggableScrollableSheet(
        initialChildSize: 0.5,
        minChildSize: 0.2,
        maxChildSize: 1,
        snap: true,
        snapSizes: [0.2, 0.5, 1.0],
        builder: (context, scrollController) {
          return Container(
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
            ),
            child: ListView.builder(
              controller: scrollController,
              itemCount: 20,
              itemBuilder: (context, index) {
                return ListTile(title: Text("Item $index"));
              },
            ),
          );
        },
      );
    },
  );
}

Or Use Stack with IgnorePointer

void _showBottomSheet(BuildContext context) {
  showBottomSheet(
    context: context,
    backgroundColor: Colors.transparent,
    builder: (context) {
      return Stack(
        children: [
    
          IgnorePointer(
            ignoring: false,
            child: GestureDetector(
              onTap: () => Navigator.pop(context), 
              behavior: HitTestBehavior.translucent,
            ),
          ),
          DraggableScrollableSheet(
            initialChildSize: 0.5,
            minChildSize: 0.2,
            maxChildSize: 1,
            snap: true,
            snapSizes: [0.2, 0.5, 1.0],
            builder: (context, scrollController) {
              return Container(
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
                ),
                child: ListView.builder(
                  controller: scrollController,
                  itemCount: 20,
                  itemBuilder: (context, index) {
                    return ListTile(title: Text("Item $index"));
                  },
                ),
              );
            },
          ),
        ],
      );
    },
  );
}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论