首页 > 解决方案 > 使用可折叠应用栏(sliverAppBar)时如何保留tabView的滚动位置?

问题描述

问题:

当 tabView 之一滚动到顶部时(显示 sliverAppBar),tabView 的滚动位置未正确恢复。另一个 tabView 也将滚动到顶部(失去其先前的滚动位置)。

问题:

使用可折叠应用栏(sliverAppBar)时如何保留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'),
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      )
    );
  }
}

标签: flutterflutter-layoutnestedscrollviewscroll-positionflutter-sliver

解决方案


这实际上是一个已知问题,并且仍然存在。尽管此线程中提到了一种解决方法:

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

它的基本要点是:

  • NestedScrollView从包装中使用extended_nested_scroll_view
  • 将每个选项卡视图包裹在一个StatefulWidgetwithAutomaticKeepAliveClientMixinwantKeepAlive => true
  • 在那个StatefulWidget(s)中,将可滚动内容包装在NestedScrollViewInnerScrollPositionKeyWidget
  • innerScrollPositionKeyBuilder使用的键值NestedScrollViewInnerScrollPositionKeyWidget必须匹配。

推荐阅读