Пользовательский просмотр прокрутки прокручивается под постоянным заголовком Sliver

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 прокручивается на вкладке sloverPersistentHeader.DefaultTabController

  • NestedScrollView
    • SliverAppBar
    • SliverPersistentHeader-body: CustomScrollView- щепки: SliverChildBuilderDelegate

SliverPersistentHeader все вкладки отображались вверху (TabBar)

Тело вложенного ScrollView - это CustomScrollView, у которого есть дочерний элемент SliverChildBuilderDelegate.

При прокрутке списка мой список прокручивается за вкладками постоянного заголовка ленты. Кажется, что sloverPersistentHeader прозрачен, а за ним можно увидеть прокрутку списка.

Чтобы решить эту проблему, я попробовал SliverOverlapInjector и SliverOverlapAbsorber, но это не помогло.

Изображение проблемы с прокруткой CustomScrollView занимает 4-е место для лучшего понимания. Карточка подсолнечного масла при прокрутке выходит за панель вкладок.

Images:
[Sliver Overlap Absorber][1]
[Sliver Overlap Injector][2]
[Custom Scroll View][3]
[Overlapping Problem][4]


  [1]: https://stackru.com/images/b2430b8a8c9ef09297591379a30ec0cf8cae3dc7.jpg
  [2]: https://stackru.com/images/c5a9e10f17085ce24f0814adb75d7e1d3a142b22.jpg
  [3]: https://stackru.com/images/5bf528f09a09ba562f78fdc071b3cc6a2bcb0849.jpg
  [4]: https://stackru.com/images/c07217652da51ecba444e9756cd32ac5ceb2a1c3.png

1 ответ

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;
  }
}

Вместо того, чтобы возвращать только виджет TabBar из SliverPersistentHeaderDelegate, оборачивая его контейнером и устанавливая backgroundColor, решите мою проблему.

Внутри метода сборки класса _ProductTabSliver я обернул контейнер

Другие вопросы по тегам