如何创建具有上部固定和下部浮动元素的 SliverAppBar?

Posted

技术标签:

【中文标题】如何创建具有上部固定和下部浮动元素的 SliverAppBar?【英文标题】:How to create a SliverAppBar, that has a upper pinned and lower floating element? 【发布时间】:2021-10-08 03:57:33 【问题描述】:

所以我想创建一个 SliverAppBar,其中上部固定并始终显示。 下半部分必须是浮动的,并且即使在未到达列表顶部时也会在向下滚动时显示。

让它对我有用的唯一方法是在彼此之上添加 2 个 sliverappbars,但我觉得这不是最好的方法。那么这将如何正确完成呢?

  return Scaffold(
      body: NestedScrollView(
        body: ListView.builder(
            itemBuilder: (context, index) => Text(index.toString())),
        headerSliverBuilder: (context, hasScrolled) 
          return [
            const SliverAppBar(
              title: Text('pinned'),
              pinned: true,
              centerTitle: true,
            ),
            const SliverAppBar(
              floating: true,
              snap: true,
              title: Text('floating'),
            ),
          ];
        ,
      ),
    );

所以从视觉上看,这就是我正在寻找的,我只是不确定实现。

【问题讨论】:

关于down sliverbar,当使用向下滚动时,才想显示? 我基本上只是想要一个普通的浮动 SliverAppBar 作为下层元素,很抱歉造成混乱 可以加个gif,还是2张图片 如果您尝试我粘贴的代码,这几乎就是我在视觉上的目标(除了第二个应用栏在向上滚动时没有出现)但我不确定它是否是推荐的技术方法。我相信一些较旧版本的 facebook 应用程序总是将 facebook 显示在固定部分,然后在其下方显示带有搜索栏的浮动部分 ***.com/a/58298462/10157127 你的情况能解决吗?还要检查***.com/a/58266900/10157127 【参考方案1】:

这样就可以了:

  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(title: Text('Title')),
      body: CustomScrollView(
        slivers: [
          SliverAppBar(
            floating: true,
            title: Text('Test'),
          ),
          SliverList(
            delegate: SliverChildBuilderDelegate(
              (context, index) => ListTile(title: Text('Item #$index')),
              childCount: 1000,
            ),
          ),
        ],
      ),
    );

【讨论】:

【参考方案2】:

这是你想要的吗,顺便说一句,它不是动画的。


class CUstomScrolling extends StatefulWidget 
  const CUstomScrolling(Key? key) : super(key: key);

  @override
  _CUstomScrollingState createState() => _CUstomScrollingState();


class _CUstomScrollingState extends State<CUstomScrolling> 
  final ScrollController controller = ScrollController();

  bool _showNavBar = true;

  @override
  void initState() 
    super.initState();

    controller.addListener(() 
      if (controller.hasClients) 
        if (controller.position.userScrollDirection ==
                ScrollDirection.forward &&
            !_showNavBar) 
          setState(() 
            _showNavBar = true;
          );
         else if (controller.position.userScrollDirection ==
                ScrollDirection.reverse &&
            _showNavBar) 
          setState(() 
            _showNavBar = false;
          );
        
      
    );
  

  @override
  void dispose() 
    controller.dispose();
    super.dispose();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: NestedScrollView(
        body: ListView.builder(
          controller: controller,
          itemBuilder: (context, index) => Text(
            index.toString(),
          ),
        ),
        headerSliverBuilder: (context, hasScrolled) 
          return [
            const SliverAppBar(
              title: Text('pinned'),
              pinned: true,
              centerTitle: true,
            ),
            if (_showNavBar)
              const SliverAppBar(
                pinned: false,
                floating: true,
                title: Text('floating'),
              ),
          ];
        ,
      ),
    );
  

【讨论】:

以上是关于如何创建具有上部固定和下部浮动元素的 SliverAppBar?的主要内容,如果未能解决你的问题,请参考以下文章

Study 8 —— 行块元素及定位

Linux常用命令精华讲解 上部 (下部下回分解)不要催很忙的

滚动时固定/浮动的div元素

三种方式实现圣杯布局

三种方式实现圣杯布局

在css中 父元素不固定高度,怎样实现子元素的高度100