带有粘性标题的颤动 DraggableScrollableSheet

时间:2021-04-14 13:28:38

标签: android ios flutter dart

我正在我的 flutter 应用程序中实现一个 DraggableScrollableSheet 并希望有一个粘性标题,即只有列表视图滚动并且工作表的顶部始终保持原位。 我的小部件如下所示:

SizedBox.expand(
    child: DraggableScrollableSheet(
      maxChildSize: 0.9,
      minChildSize: 0.2,
      initialChildSize: 0.3,
      expand: false,
      builder:
          (BuildContext context, ScrollController scrollController) {
        return Container(
          decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.only(
                topLeft: Radius.circular(20),
                topRight: Radius.circular(20),
              )),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Align(
                alignment: Alignment.topCenter,
                child: Container(
                  margin: EdgeInsets.symmetric(vertical: 8),
                  height: 8.0,
                  width: 70.0,
                  decoration: BoxDecoration(
                      color: Colors.grey[400],
                      borderRadius: BorderRadius.circular(10.0)),
                ),
              ),
              SizedBox(height: 16),
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 24),
                child: Text(
                  'Neuigkeiten',
                  style: TextStyle(
                      fontSize: 20, fontWeight: FontWeight.bold),
                ),
              ),
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 24),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    SizedBox(height: 20.0),
                    Text('Erfahre mehr ... '),
                  ],
                ),
              ),
              SizedBox(height: 16),
              Expanded(child: NewsList(controller: scrollController))
            ],
          ),
        );
      },
    ),
  );

基本功能有效,但只有在列表视图项上拖动/滚动时,工作表才可拖动和滚动。我需要进行哪些更改才能使列中的其他小部件也可滚动。我在没有解决方案的情况下尝试了 Scrollable 和 Draggable 小部件。

感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

问题在于 ListView 本身。为此,您需要使用 SliverList,检查 this answer

 Widget _buildDiscoverDrawer() {
    return DraggableScrollableSheet(
        maxChildSize: 0.95,
        minChildSize: 0.25,
        initialChildSize: 0.4,
        builder: (context, scrollController) {
          List<Widget> _sliverList(int size, int sliverChildCount) {
            List<Widget> widgetList = [];
            for (int index = 0; index < size; index++)
              widgetList
                ..add(SliverAppBar(
                  title: Text("Title $index"),
                  pinned: true,
                ))
                ..add(SliverFixedExtentList(
                  itemExtent: 50.0,
                  delegate: SliverChildBuilderDelegate(
                      (BuildContext context, int index) {
                    return Container(
                      alignment: Alignment.center,
                      color: Colors.lightBlue[100 * (index % 9)],
                      child: Text('list item $index'),
                    );
                  }, childCount: sliverChildCount),
                ));

            return widgetList;
          }

          return CustomScrollView(
            controller: scrollController,
            slivers: _sliverList(50, 10),
          );
        });
  }

答案 1 :(得分:0)

video tutorial 表示 builder 应该返回一个可滚动的小部件,例如 SingleChildScrollViewListView。您是否尝试过使用其中之一而不是 Container

答案 2 :(得分:0)

您可以通过使用 Stack 作为工作表的内容来实现此目的。这样,您可以使 ListView 跨越工作表的整个尺寸(因此即使您触摸标题也可以拖动它),并将标题作为叠加层放在顶部。不过,请确保在列表顶部添加一些填充,以免隐藏标题下的第一项。

您必须确保标题不会消耗滑动事件。例如,我想在顶部使用 AppBar,但该小部件消耗了滑动事件。如果您想使用消耗这些事件的小部件,则应将其包装在 IgnorePointer() 中。

这是 flutter 文档中的示例,但现在带有粘性 AppBar 标头。

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('DraggableScrollableSheet'),
      ),
      body: SizedBox.expand(
        child: DraggableScrollableSheet(
          builder: (BuildContext context, ScrollController scrollController) {
            return Stack(
              children: [

                //this section is your list
                Container(
                  color: Colors.blue[100],
                  child: ListView.builder(
                    controller: scrollController,
                    itemCount: 26,
                    itemBuilder: (BuildContext context, int index) {
                      if(index == 0)return Container(height: 50);//this is the padding on the top of the list
                      return ListTile(title: Text('Item ${index-1}'));
                      },
                  ),
                ),

                //this section is your header
                IgnorePointer(
                  child: Container(
                    height: 50,
                    child: AppBar(
                      title: Text("Sheet title"),
                      automaticallyImplyLeading: false,//this prevents the appBar from having a close button (that button wouldn't work because of IgnorePointer)
                    ),
                )),
              ],
            );
          },
        ),
      ),
    );
  }
}