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

嵌套TabView中的任意一个Tab不满一屏,导致所有Tab都不可滑动 #36

Closed pjyx closed 2 years ago

pjyx commented 4 years ago

_NestedScrollCoordinator的updateCanDrag和hasScrolledBody函数,取innerPositions时用_innerPositions替代_currentInnerPositions。这样就不会由某一个Tab的可滑动性作为全部inner可滑动性。

zmtzawqlp commented 4 years ago

1.12.13之后,我发现innerpostion,不管缓存不,都只有一个了。。可怕,我昨天晚上调试了下官方的,我要多花点时间研究下这个变动。。

pjyx commented 4 years ago

我现在是1.17.1, _innerPositions是有多个的,没出现仅有一个的情况。

zmtzawqlp commented 4 years ago

我昨天1.12.13 ,1.17都试过。只有一个,我做了列表缓存,很神奇呢。。你说的问题。可以放一个最简单的demo。。免得大家最好场景不一样

pjyx commented 4 years ago

我写了一个简单的demo,但是不能完全复现我们真实的代码的现象。DEMO中滑动TAB会重新走updateCanDrag,使得第一次滑动不了,松手之后再滑就可以了。 现在还没搞清楚为什么我们的代码切TAB不会重新_NestedScrollController.attach,滑动会重新走updateCanDrag。 但还是可以复现滑不动的情况,复现步骤: 1.在第一个TAB(不满一屏)点击item进二级页返回,切到第二个TAB(超过一屏),滑不动。 代码如下: import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:loading_more_list/loading_more_list.dart';

class TestExtendedNestedScrollView extends StatefulWidget{ @override _State createState() { return _State(); }

}

class _State extends State with TickerProviderStateMixin, AutomaticKeepAliveClientMixin {

GlobalKey _globalKey = GlobalKey(); List _tabs = ['tab1', 'tab2']; List _pages; ScrollController _scrollController; TabController _tabController;

GlobalObjectKey tab1Key = GlobalObjectKey('tab1'); GlobalObjectKey tab2Key = GlobalObjectKey('tab2');

@override void initState() { super.initState(); _pages = [ TestList(['tab1_item1'], 'tab1', tab1Key), TestList(['tab2_item1', 'tab2_item2', 'tab2_item3', 'tab2_item4', 'tab2_item5', 'tab2_item6', 'tab2_item7', 'tab2_item8', 'tab2_item9', 'tab2_item10', 'tab2_item11', 'tab2_item12', 'tab2_item13', 'tab2_item14', 'tab2_item15', 'tab2_item16', 'tab2_item17', 'tab2_item18', 'tab2_item19', 'tab2_item20'], 'tab2', tab2Key), ]; _scrollController = ScrollController(); _tabController = TabController(length: _tabs.length, vsync: this); }

@override Widget build(BuildContext context) { return Scaffold( key: _globalKey, resizeToAvoidBottomInset: false, appBar: AppBar( title: Text('TestExtendedNestedScrollView'), ), // body: TestList(['tab2_item1', 'tab2_item2', 'tab2_item3', 'tab2_item4', 'tab2_item5', // 'tab2_item6', 'tab2_item7', 'tab2_item8', 'tab2_item9', 'tab2_item10', // 'tab2_item11', 'tab2_item12', 'tab2_item13', 'tab2_item14', 'tab2_item15', // 'tab2_item16', 'tab2_item17', 'tab2_item18', 'tab2_item19', 'tab2_item20']), body: NestedScrollView( physics: ClampingScrollPhysics(), controller: _scrollController, headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return [ SliverAppBar( brightness: Brightness.light, backgroundColor: Colors.red, automaticallyImplyLeading: false, elevation: 0.0, expandedHeight: kToolbarHeight, pinned: true, floating: false, snap: false, ), ]; }, pinnedHeaderSliverHeightBuilder: () { return MediaQuery.of(context).padding.top + kToolbarHeight; }, innerScrollPositionKeyBuilder: () { return Key(_getPageKey(_tabController.index)); }, body: Column( children: [ TabBar( tabs: [ Text( _tabs[0], ), Text( _tabs[1], ), ], controller: _tabController, ), Expanded( child: TabBarView( physics: ClampingScrollPhysics(), controller: _tabController, children: _pages, ), ), ], ), ), ); }

String _getPageKey(int index) { String key; if (index == 0) { key = 'tab1'; } else if (index == 1) { key = 'tab2'; } return key; }

@override bool get wantKeepAlive => true; }

class TestList extends StatefulWidget {

final List items; final String viewKey;

TestList(this.items, this.viewKey, Key key) : super(key: key);

@override TestListState createState() { return TestListState(); } }

class TestListState extends State {

@override Widget build(BuildContext context) { return Padding( padding: EdgeInsetsDirectional.only(bottom: 10), child: NestedScrollViewInnerScrollPositionKeyWidget( Key('${widget.viewKey}'), CustomScrollView( slivers: [ SliverFixedExtentList( delegate: SliverChildBuilderDelegate((BuildContext context, int index) { return buildItem(context, widget.items[index]); }, childCount: widget.items.length, addAutomaticKeepAlives: true), itemExtent: 60, ) ], ), ), ); }

Widget buildItem(BuildContext context, String text) { return GestureDetector( onTap: () async { Navigator.push(context, MaterialPageRoute( builder: (c) { return TestDetail(text); } )); }, child: ListTile( title: Text( text, ), ), ); }

}

class TestDetail extends StatelessWidget { final String text; TestDetail(this.text);

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('TestDetail'), ), body: Center( child: Text(text), ), ); }

}

zmtzawqlp commented 2 years ago

现在还有问题吗?

zmtzawqlp commented 2 years ago

当前版本无法重现