在 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(),
),
),
),
);
}
}