使用可折叠应用栏(sliverAppBar)时如何保留tabView的滚动位置?

Posted

技术标签:

【中文标题】使用可折叠应用栏(sliverAppBar)时如何保留tabView的滚动位置?【英文标题】:How to preserve the scroll position of tabView when using collapsible app bar (sliverAppBar)? 【发布时间】:2018-12-30 04:58:44 【问题描述】:

问题:

tabView 的滚动位置在其中一个 tabView 滚动到顶部时正确恢复(显示 sliverAppBar)。另一个 tabView 也会滚动到顶部(失去之前的滚动位置)。

如果使用普通的应用栏,这个问题不会出现(不是可折叠的应用栏) 此问题在 tabView 滚动到顶部时出现

问题:

代码:

import 'package:flutter/material.dart';

void main() 
  runApp(new MyApp());


class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return new MaterialApp(
      home: new MyHomePage(),
    );
  


class MyHomePage extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return new DefaultTabController(
      length: 2,
      child: Scaffold(
        body: NestedScrollView(
          headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) 
            return <Widget>[
              SliverAppBar(
                title: Text('Example'),
                pinned: true,
                floating: true,
                forceElevated: innerBoxIsScrolled,
                bottom: TabBar(
                  tabs: <Widget>[
                    Tab(text: 'One',),
                    Tab(text: 'Two'),
                  ],
                ),
              ),
            ];
          ,
          body: TabBarView(
            children: <Widget>[
              Center(
                key: PageStorageKey<String>('one'),
                child: ListView.builder(
                  itemBuilder: (BuildContext context, int index) 
                    return new ListTile(
                      title: new Text('One Item $index'),
                    );
                  ,
                ),
              ),
              Center(
                key: PageStorageKey<String>('two'),
                child: ListView.builder(
                  itemBuilder: (BuildContext context, int index) 
                    return new ListTile(
                      title: new Text('Two Item $index'),
                    );
                  ,
                ),
              ),
            ],
          ),
        ),
      )
    );
  

【问题讨论】:

这个功能是由 Flutter 开发团队添加的,所以现在它默认工作了 【参考方案1】:

这实际上是一个known issue 并且仍然打开。虽然有mentioned in this thread这样的解决方法:

这是一个使用 extended_nested_scroll_view 包裹。有了这个,我没有遇到任何问题(至少对于 现在)。所以在颤振解决这个问题之前,这个解决方法似乎 充足的。仅在 android 上测试。

它的基本要点是:

使用包中的NestedScrollView extended_nested_scroll_viewAutomaticKeepAliveClientMixinwantKeepAlive =&gt; true 将每个选项卡视图包装在StatefulWidget 中 在StatefulWidget(s) 中,将可滚动内容包装在NestedScrollViewInnerScrollPositionKeyWidgetinnerScrollPositionKeyBuilderNestedScrollViewInnerScrollPositionKeyWidget 中使用的键值必须匹配。

【讨论】:

以上是关于使用可折叠应用栏(sliverAppBar)时如何保留tabView的滚动位置?的主要内容,如果未能解决你的问题,请参考以下文章

使 SliverAppBar 具有图像作为背景而不是颜色

我如何制作一个类似于Google新闻的SliverAppBar?

无法删除 sliver 应用栏中的后退按钮

如何在点击时隐藏可折叠的 Bootstrap 导航栏

向下滚动时隐藏的 Flutter TabBar 和 SliverAppBar

使用 Bootstrap 4,如何在移动/平板电脑视图中折叠侧边栏