2
DefaultTabController(
          length: _subCategory.tabLength,
          initialIndex: 0,
          child:
NestedScrollView(
      physics: BouncingScrollPhysics(),
      headerSliverBuilder: (headerCtx, innnerBoxIsScrolled) {
        return <Widget>[
          SliverAppBar(
            expandedHeight: 200.0,
            backgroundColor: _productColor.backgroundColor,
            pinned: true,
            elevation: 0,
            forceElevated: innnerBoxIsScrolled,
            flexibleSpace: FlexibleSpaceBar(
              title: Text("${_subCategory.currentSubCategoryName()}"),
              background: Container(
                margin: const EdgeInsets.only(
                  top: 4,
                  bottom: 50.0,
                ),
                child: Hero(
                  tag: _subCategory.currentSubCategoryId(),
                  child: Image.asset(
                    'asset/images/grocery.jpeg',
                  ),
                ),
              ),
            ),
          ),
          SliverOverlapAbsorber(
            handle: NestedScrollView.sliverOverlapAbsorberHandleFor(headerCtx),
            sliver: SliverPersistentHeader(
              pinned: true,
              delegate: _ProductTabSliver(
                TabBar(
                  labelColor: Colors.white,
                  unselectedLabelColor: Colors.black87,
                  tabs: [
                    ..._subCategory.currentTab().map(
                      (tabValue) {
                        return Tab(text: "${tabValue.fullName}");
                      },
                    ).toList()
                  ],
                ),
              ),
            ),
          ),
        ];
      },
      body:CustomScrollView(
      physics: BouncingScrollPhysics(),
      slivers: <Widget>[
        SliverOverlapInjector(
          handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
        ),
        SliverList(
          delegate: SliverChildBuilderDelegate(
            (ctx, pdIndex) {
              final heightVisible =
                  _subCategory.advanceCompanyProductCount(pdIndex);
           
           return ProductLayout();
 },
            childCount: _subCategory.differentProductCount(),
          ),
        ),
      ],
    );,
    ));

CustomScrollList 在 sliverPersistentHeader 选项卡下滚动。默认选项卡控制器

  • 嵌套滚动视图
    • SliverAppBar
    • SliverPersistentHeader -body: CustomScrollView - slivers: SliverChildBuilderDelegate

SliverPersistentHeader 的所有选项卡都显示在顶部(TabBar)

Nested ScrollView 的主体是 CustomScrollView ,它有 SliverChildBuilderDelegate 有一个孩子。

在滚动列表时,我的列表滚动到 sliver 持久标题的选项卡后面。似乎 sliverPersistentHeader 是透明的,后面可以看到列表滚动。

为了解决这个问题,我尝试了 SliverOverlapInjector 和 SliverOverlapAbsorber,但这并没有帮助。

CustomScrollView 滚动问题图像是第 4 个,以便更好地理解。滚动时的葵花籽油卡片到达标签栏后面。

图片:

银重叠吸收器

银重叠喷油器

自定义滚动视图

重叠问题

4

1 回答 1

3
class ProductAppBar extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
  
    return NestedScrollView(
      physics: BouncingScrollPhysics(),
      headerSliverBuilder: (headerCtx, innnerBoxIsScrolled) {
        return <Widget>[
          SliverAppBar(
            expandedHeight: 200.0,
            backgroundColor: _productColor.backgroundColor,
            pinned: true,
            elevation: 0,
            forceElevated: innnerBoxIsScrolled,
            flexibleSpace: FlexibleSpaceBar(
              title: Text("${_subCategory.currentSubCategoryName()}"),
              background: Container(
                margin: const EdgeInsets.only(
                  top: 4,
                  bottom: 50.0,
                ),
                child: Hero(
                  tag: _subCategory.currentSubCategoryId(),
                  child: Image.asset(
                    'asset/images/grocery.jpeg',
                  ),
                ),
              ),
            ),
          ),
          SliverOverlapAbsorber(
            handle: NestedScrollView.sliverOverlapAbsorberHandleFor(headerCtx),
            sliver: SliverPersistentHeader(
              pinned: true,
              delegate: _ProductTabSliver(
                TabBar(
                  onTap: (index) {
                    _subCategory.updateTabIndex(index);
                  },
                  labelColor: Colors.white,
                  unselectedLabelColor: Colors.black87,
                  tabs: [
                    ..._subCategory.currentTab().map(
                      (tabValue) {
                        return Tab(text: "${tabValue.fullName}");
                      },
                    ).toList()
                  ],
                ),
              ),
            ),
          ),
        ];
      },
      body: TabBarView(
        children: _subCategory.currentTab().map((tabElement) {
          return ProductScreenLayout();
        }).toList(),
      ),
    );
  }
}

class _ProductTabSliver extends SliverPersistentHeaderDelegate {
  final TabBar _tabBar;

  _ProductTabSliver(this._tabBar);

  @override
  Widget build(
      BuildContext context, double shrinkOffset, bool overlapsContent) {
    final _productColor =
        Provider.of<ColorConfig>(context, listen: false).randomProductColor();

    return Container(
        decoration: BoxDecoration(
          color: _productColor.backgroundColor,
        ),
        child: _tabBar);
  }

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

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

  @override
  bool shouldRebuild(SliverPersistentHeaderDelegate oldDelegate) {
    return false;
  }
}

而不是从 SliverPersistentHeaderDelegate 只返回 TabBar Widget,用 Container 包装它并设置 backgroundColor 解决了我的问题。

在类 _ProductTabSliver 构建方法中,我已经包装了 Container

于 2020-06-24T20:31:23.557 回答