嵌套滚动条问题:NestedScrollView,SliverAppBar,SliverPersistentHeader,TabBarView和PageView

时间:2018-09-15 17:00:32

标签: flutter flutter-sliver

这个问题困扰了我一段时间,尽管我阅读了无数网页,但仍然无法解决。也许您可以帮忙!

我遇到以下情况:

Flutter应用程序的PageView只有3页。

第一页有一个简单的GridView(垂直滚动),嵌套滚动在那里没有问题。

第三页是一个简单的ListView,其中包含项目列表,在这里滚动也没有问题。

第二页有一个NestedScrollView,其headerSliverBuilder有两个小部件:SliverAppBarSliverPersistentHeader。这里没什么好看的。

NestedScrollView的主体包含一个TabBarView,其中包含3个标签,可以使用水平滑动在它们之间进行滑动-与包含PageView的滑动方向相同此页面。

主体是发生滚动问题的地方。

在三个选项卡之间滑动就像一个超级按钮。但是,如果当前标签页是第一个,并且您尝试向左进一步滑动(手指运动是从左到右),则不会显示第一页(属于PageView)。相反,当当前选项卡位于第三个选项卡时,如果您尝试向右进一步滑动(手指的运动是从右到左),则什么也没有发生。

如果您对第二页中的页眉进行相同的手指运动,则这些页会变好(翻到第一页或第三页)。

这是第二页中的代码,很想知道为什么当标签到达边缘时,TabBarView内的滑动运动没有传播到容器:

Scaffold(
  appBar: _generateAppBar(),
  body: DefaultTabController(
    length: 3,
    child: NestedScrollView(
      headerSliverBuilder: (_, __) => [
        SliverAppBar(
          backgroundColor: backgroundColor,
          elevation: 0.0,
          expandedHeight: 200.0,
          floating: true,
          pinned: false,
          flexibleSpace: backgroundImageView,
        ),
        SliverPersistentHeader(
          floating: false,
          delegate: _SliverAppBarDelegate(
            TabBar(
              labelColor: Theme.of(context).primaryColor,
              unselectedLabelColor: Colors.black26,
              indicatorWeight: 2.5,
              tabs: const [
                Text('Tab 1'),
                Text('Tab 2'),
                Text('Tab 3'),
              ],
            ),
          ),
          pinned: true,
        ),
      ],
      body: TabBarView(
        children: [
          Center(child: Text('Body 1')),
          Center(child: Text('Body 2')),
          Center(child: Text('Body 3')),
        ],
      ),
    ),
  ),
);

辅助类:

class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
  _SliverAppBarDelegate(this._tabBar);

  final TabBar _tabBar;

  @override
  double get minExtent => _tabBar.preferredSize.height;

  @override
  double get maxExtent => _tabBar.preferredSize.height;

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) =>
    Container(child: _tabBar);

  @override
  bool shouldRebuild(_SliverAppBarDelegate oldDelegate) =>
    false;
}

有人知道如何解决此问题吗?谢谢!

1 个答案:

答案 0 :(得分:0)

您应该将  NestedScrollView

DefaultTabController( length: tabs.length, child: NestedScrollView())