求助,关于 Flutter 的 NestedScrollView 与 Scrollbar 冲突
資深大佬 : alvazu 39
在 Stackoverflow 上找了一圈也没有找到答案,想向 v2 的朋友们求助一下。
NestedScrollView
+ SliverAppBar
+ TabView
与Scrollbar
合用,在左右滑动时出现以下错误:
The following assertion was thrown while notifying status listeners for AnimationController: The PrimaryScrollController is currently attached to more than one ScrollPosition.
我尝试过用PrimaryScrollController
包裹Scroller 组件
,错误不再出现,但是NestedScrollView
上下两边的滚动不再同步;尝试过写NotificationListener
,问题看起来解决了,但是会有奇怪的卡顿现象:
NotificationListener<ScrollNotification>( onNotification: (ScrollNotification notification) { //print(notification.metrics.axisDirection); if (notification.metrics.extentAfter > 0 && notification.metrics.extentBefore > 0 && notification.metrics.axisDirection == AxisDirection.down) { double pixelnow = notification.metrics.pixels; double _jmpTo = _scrollController.offset + (pixelnow - _scrollLocation); //print("pixel now : $pixelnow"); //print("jumpto: $_jmpTo"); if (_scrollController.position.maxScrollExtent >= _scrollController.offset && _scrollController.offset >= _scrollController.position.minScrollExtent ){ _scrollController.jumpTo(_jmpTo); //_scrollController.jumpTo(value) } _scrollLocation = pixelnow; } return false; },
我的原始代码如下:
import 'package:flutter/material.dart'; void main() => runApp(MaterialApp(home: Scaffold(body: CommunityPage()))); class CommunityPage extends StatefulWidget { CommunityPage({Key? key}) : super(key: key); @override _CommunityPageState createState() => _CommunityPageState(); } class _CommunityPageState extends State<CommunityPage> { //ScrollController _scrollController = ScrollController(); //final TabController _tabController = TabController(); final _tabs = <String>["Tab 1", "Tab 2", "Tab 3"]; @override Widget build(BuildContext context) { return Scaffold( body: DefaultTabController( length: _tabs.length, // This is the number of tabs. child: NestedScrollView( headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { // These are the slivers that show up in the "outer" scroll view. return <Widget>[ SliverOverlapAbsorber( handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), sliver: SliverAppBar( automaticallyImplyLeading: false, title: const Text("Community",style: TextStyle(color: Colors.black)), //centerTitle: false, pinned: true, floating: true, snap: true, backgroundColor: Colors.grey[50], expandedHeight: 85.0, bottom: TabBar( tabs: _tabs.map((String name) => Tab(text: name)).toList(), ), ), ), ]; }, body: TabBarView( children: _tabs.map((String name) { //SafeArea 适配刘海屏的一个 widget return Builder( builder: (BuildContext context) { return Scrollbar( child: CustomScrollView( key: PageStorageKey<String>(name), slivers: <Widget>[ SliverOverlapInjector( handle: NestedScrollView.sliverOverlapAbsorberHandleFor( context), ), SliverFixedExtentList( itemExtent: 50.0, //item 高度或宽度,取决于滑动方向 delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { return ListTile( title: Text('Item $index'), ); }, childCount: 30, ), ), ], ), ); }, ); }).toList(), ), ), ), ); } }
大佬有話說 (0)