fluttercandies / extended_nested_scroll_view

extended nested scroll view to fix following issues. 1.pinned sliver header issue 2.inner scrollables in tabview sync issue 3.pull to refresh is not work. 4.do without ScrollController in NestedScrollView's body
MIT License
592 stars 119 forks source link

1.SliverPadding 组件会叠加在pinned上 2.SliverPersistentHeader overlapsContent 和 shrinkOffset 失效 #34

Closed dazed-daydreamer closed 2 years ago

dazed-daydreamer commented 4 years ago

import 'package:flutter/material.dart' hide NestedScrollView; import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';

void main() { runApp(MyApp()); }

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }

class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key);

final String title; @override _MyHomePageState createState() => _MyHomePageState(); }

class _MyHomePageState extends State with SingleTickerProviderStateMixin { TabController tabController; @override void initState() { super.initState(); this.tabController = TabController(length: 4, vsync: this); }

Future _onRefresh() {}

//tab Widget _tabListWidget(bool ceiling) { return Container( padding: EdgeInsets.symmetric(horizontal: 15), color: ceiling ? Colors.white : Colors.transparent, height: 50, child: TabBar( labelColor: Colors.black, controller: this.tabController, indicatorWeight: 3.5, indicatorSize: TabBarIndicatorSize.label, indicatorColor: Colors.red, labelStyle: TextStyle(fontSize: 17, fontWeight: FontWeight.bold), unselectedLabelStyle: TextStyle( fontSize: 15, ), tabs: [ Tab(text: '精选产品'), Tab(text: '吃货联盟'), Tab(text: '电脑办公'), Tab(text: '生活家电'), ], ), ); }

//tabview Widget _tabViewWidget() { return Container( child: ListView.builder( itemBuilder: (BuildContext context, int index) { return Container( height: 30, child: Text('$index'), ); }, itemCount: 100, ), ); }

@override Widget build(BuildContext context) { final double statusBarHeight = MediaQuery.of(context).padding.top; return Scaffold( body: NestedScrollViewRefreshIndicator( onRefresh: _onRefresh, child: NestedScrollView( headerSliverBuilder: (context, ceiling) { return [ //搜索框 SliverAppBar( pinned: true, elevation: 0, title: Text('搜索栏'), ),

              //间隔
              SliverPadding(
                padding: EdgeInsets.all(20),
              ),

              SliverToBoxAdapter(
                child: Container(
                  height: 1500,
                  color: Colors.red,
                ),
              ),

              //间隔
              SliverPadding(
                padding: EdgeInsets.all(20),
              ),

              // tab头部
              SliverPersistentHeader(
                pinned: true,
                delegate: StickyTabBarDelegate(
                  child: this._tabListWidget(false),
                  ceiling: this._tabListWidget(true),
                ),
              ),
            ];
          },
          pinnedHeaderSliverHeightBuilder: () {
            return statusBarHeight + kToolbarHeight + 50;
          },
          innerScrollPositionKeyBuilder: () {
            var index = "Tab";
            index += tabController.index.toString();
            return Key(index);
          },
          body: TabBarView(
            controller: this.tabController,
            children: <Widget>[
              NestedScrollViewInnerScrollPositionKeyWidget(
                  Key("Tab0"), _tabViewWidget()),
              NestedScrollViewInnerScrollPositionKeyWidget(
                  Key("Tab1"), _tabViewWidget()),
              NestedScrollViewInnerScrollPositionKeyWidget(
                  Key("Tab2"), _tabViewWidget()),
              NestedScrollViewInnerScrollPositionKeyWidget(
                  Key("Tab3"), _tabViewWidget()),
            ],
          ))),
);

} }

class StickyTabBarDelegate extends SliverPersistentHeaderDelegate { final child; final ceiling;

StickyTabBarDelegate({@required this.child, @required this.ceiling});

@override Widget build( BuildContext context, double shrinkOffset, bool overlapsContent) { return overlapsContent ? this.ceiling : this.child; }

@override double get maxExtent => 50;

@override double get minExtent => 50;

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

dazed-daydreamer commented 4 years ago

SliverPadding( padding: EdgeInsets.all(20), ),

会自动叠加到pinned上。

dazed-daydreamer commented 4 years ago

pinnedHeaderSliverHeightBuilder 如果设pinned 的总高度,overlapsContent 和 shrinkOffset不触发。当设pinnedHeaderSliverHeightBuilder 的数值少于 pinned 总高度 ,overlapsContent 和 shrinkOffset才会触发

测试该问题的时候请先把SliverPadding组件删除

zmtzawqlp commented 2 years ago

如果你用的官方的SliverPersistentHeader,那是不是应该用官方的组件?