首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CustomScrollView中有多个SliverAppBar

CustomScrollView中有多个SliverAppBar
EN

Stack Overflow用户
提问于 2019-05-05 21:24:21
回答 1查看 1.8K关注 0票数 0

我需要有多个SliverAppBar,每个在一个单一的视图中有自己的SliverList。当前只有第一个SliverAppBar正确响应。

当然,我已经在SO和Google上做了扩展搜索,但还没有找到解决方案!

代码语言:javascript
复制
  @override
  Widget build(BuildContext context) {
     return Scaffold(
        appBar: AppBar(
          title: Text('Details'),
        ),
        body: CustomScrollView(
          slivers: <Widget>[
            new SliverAppBar(
              floating: true,
              automaticallyImplyLeading: false,
              title: Text('1'),
            ),
            new SliverList(
              delegate: SliverChildBuilderDelegate(
                (context, index) => ListTile(title: Text('Text 1')),
                childCount: 20,
              ),
            ),
            new SliverAppBar(
              automaticallyImplyLeading: false,
              title: Text('2'),
              floating: true,
            ),
            new SliverList(
              delegate: SliverChildBuilderDelegate(
                (context, index) => ListTile(title: Text('Text 2')),
                childCount: 20,
              ),
            ),
          ],
        ),
      );
  }

如果你滚动,我希望当你滚动列表时,标题"2“也会浮动。

EN

回答 1

Stack Overflow用户

发布于 2019-05-06 09:56:39

这似乎是CustomScrollView的一个局限性。解决这个问题是可能的,但这是非常棘手的,除非你有固定高度的项目和固定长度的列表。如果是这样,你可以假设整个会话的高度(AppBar高度+每个列表项的高度)。

看一看:

代码语言:javascript
复制
class Foo extends StatefulWidget {
  @override
  _FooState createState() => _FooState();
}

class _FooState extends State<Foo> {
  static const double listItemHeight = 50;
  static const int listItemCount = 15;

  static const double sessionHeight = kToolbarHeight + (listItemCount * listItemHeight);

  int floatingAppBarIndex;
  ScrollController controller;

  @override
  void initState() {
    super.initState();
    floatingAppBarIndex = 0;
    controller = ScrollController()..addListener(onScroll);
  }

  void onScroll() {
    double scrollOffset = controller.offset;
    int sessionsScrolled = 0;

    while (scrollOffset > sessionHeight) {
      scrollOffset -= sessionHeight;
      sessionsScrolled++;
    }

    if (sessionsScrolled != floatingAppBarIndex) {
      setState(() {
        floatingAppBarIndex = sessionsScrolled;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Details'),
      ),
      body: CustomScrollView(
        controller: controller,
        slivers: <Widget>[
          new SliverAppBar(
            floating: floatingAppBarIndex == 0,
            automaticallyImplyLeading: false,
            title: Text('1'),
          ),
          new SliverList(
            delegate: SliverChildBuilderDelegate(
              (context, index) {
                return SizedBox(
                  height: listItemHeight,
                  child: ListTile(
                    title: Text('Text 1'),
                  ),
                );
              },
              childCount: listItemCount,
            ),
          ),
          new SliverAppBar(
            floating: floatingAppBarIndex == 1,
            automaticallyImplyLeading: false,
            title: Text('2'),
          ),
          new SliverList(
            delegate: SliverChildBuilderDelegate(
              (context, index) {
                return SizedBox(
                  height: listItemHeight,
                  child: ListTile(
                    title: Text('Text 2'),
                  ),
                );
              },
              childCount: listItemCount,
            ),
          ),
        ],
      ),
    );
  }
}

正如我所说的,您仍然可以在具有可变值(项高度和列表长度)的列表中做到这一点,但这将非常非常棘手。如果您遇到这种情况,我建议您使用以下插件之一:https://pub.dartlang.org/packages/sticky_headers https://pub.dartlang.org/packages/flutter_sticky_header

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55992401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档