【问题标题】:How to put a Stack as a child of CustomScrollView如何将 Stack 作为 CustomScrollView 的子项
【发布时间】:2019-11-14 09:08:42
【问题描述】:

我正在使用 CustomScrollView。我在其中添加了一些条子,但我的一个孩子必须是一个堆栈,其中有一个列表,就像它的两个孩子一样。我尝试使用 SliverToBoxAdapter 但这使得堆栈中的列表不可滚动,这是显而易见的行为。有没有办法编写某种 SliverToSliverAdapter?我尝试阅读 SliverPadding,但它看起来太复杂了,我无法理解。以下是我的代码:

  CustomScrollView(
        key: PageStorageKey<String>(name),
        slivers: <Widget>[
          SliverOverlapInjector(
              handle:
                  NestedScrollView.sliverOverlapAbsorberHandleFor(context)),
          SliverToBoxAdapter(
              child: Stack(
            children: <Widget>[
              Container(
                width: double.infinity,
                height: 50,
                decoration: BoxDecoration(color: pink),
              ),
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 30),
                child: ListView.builder(
                  padding: const EdgeInsets.all(0),
                  shrinkWrap: true,
                  itemBuilder: (context, index) {
                    return buildSongRow(songs[index]);
                  },
                  itemCount: songs.length,
                ),
              )
            ],
          )),
        ],
      );

【问题讨论】:

    标签: flutter dart flutter-layout flutter-sliver


    【解决方案1】:

    Stack 小部件默认使用父级的大小。虽然父小部件是CustomScrollView,它决定了它的大小平均值,但它将获得无限的高度。为了解决这个问题,我们可以用SizedBox(height:x)包裹Stack

    下一个问题出现在Stack,关于滚动和小部件可见性。小部件渲染从下到上优先级,滚动事件的优先级相同。虽然Container(height:50)Stack 的第一个孩子,但它将在ListView 后面绘制,在这种情况下,我们可以在ListView 上进行全滚动事件。

    我们可以移动底部的Container&lt;height:50&gt; 以将其绘制在ListView 上。在这种情况下,滚动事件不会在Container&lt;h:50&gt; 部分起作用。

    我们可以通过提供heightContainer&lt;h:50&gt;ListViewSizedBox 包装起来,并使用AlignPositioned 小部件将它们放置在Stack 上。此外,我们可以增加itemCount+1 并使用一个空的SizedBox(height:50)(在索引0 上),它的高度与Container(height:50) 相同,并有助于在Stack 上仅查看第一次。

    我正在使用LayoutBuilder 来获取屏幕的大小/约束。

    return Scaffold(
          body: LayoutBuilder(
            builder: (context, constraints) => CustomScrollView(
              slivers: [
                const SliverAppBar(
                  title: Text("Stack On CustomScrollView"),
                ),
                SliverToBoxAdapter(
                  child: SizedBox(
                    height: constraints.maxHeight * .3, // used by stack
                    child: Stack(
                      children: [
                        Align(
                          alignment: Alignment.topCenter,
                          child: Container(
                            // dont need to use sizedBox here, height is fixed by container's height:50
                            height: 50,
                            color: Colors.pink,
                            alignment: Alignment.center,
                            child: const Text("Stack Child: Container<height: 50>"),
                          ),
                        ),
                        Align(
                          alignment: Alignment.bottomCenter,
                          child: SizedBox(
                            height: constraints.maxHeight * .3 - 50,
                            child: ListView.builder(
                              itemCount: 4,
                              itemBuilder: (context, index) => Container(
                                alignment: Alignment.center,
                                height: 50,
                                color: index.isEven
                                    ? Colors.deepOrange
                                    : Colors.deepPurple,
                                child: Text("ListViewItem:$index"),
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
                SliverList(
                  delegate: SliverChildListDelegate(
                    [
                      ...List.generate(
                        44,
                        (index) => Container(
                          height: 100,
                          alignment: Alignment.center,
                          color: index.isEven ? Colors.cyanAccent : Colors.blueGrey,
                          child: Text("SliverList $index"),
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        );
    

    【讨论】:

    • 如果你愿意,内滚动结束时需要处理两个滚动事件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 2018-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多