写点什么

Flutter 扩展 NestedScrollView (二)列表滚动同步解决

用户头像
Android架构
关注
发布于: 10 小时前

final Key scrollPositionKey;final Widget child;NestedScrollViewInnerScrollPositionKeyWidget(this.scrollPositionKey, this.child);@override_NestedScrollViewInnerScrollPositionKeyWidgetState createState() =>_NestedScrollViewInnerScrollPositionKeyWidgetState();}


class _NestedScrollViewInnerScrollPositionKeyWidgetStateextends State<NestedScrollViewInnerScrollPositionKeyWidget> {@overrideWidget build(BuildContext context) {return widget.child;}


// @override// void didChangeDependencies() {// // TODO: implement didChangeDependencies// //print("didChangeDependencies"+widget.scrollPositionKey.toString());// super.didChangeDependencies();// }//// @override// void didUpdateWidget(NestedScrollViewInnerScrollPositionKeyWidget oldWidget) {// // TODO: implement didUpdateWidget// //print("didUpdateWidget"+widget.scrollPositionKey.toString()+oldWidget.scrollPositionKey.toString());// super.didUpdateWidget(oldWidget);// }}


然后在刚才 attach 方法中通过先祖 NestedScrollViewInnerScrollPositionKeyWidget


@overridevoid attach(ScrollPosition position) {assert(position is _NestedScrollPosition);


super.attach(position);attachScrollPositionKey(position as _NestedScrollPosition);coordinator.updateParent();coordinator.updateCanDrag();position.addListener(_scheduleUpdateShadow);_scheduleUpdateShadow();}


@overridevoid detach(ScrollPosition position) {assert(position is _NestedScrollPosition);position.removeListener(_scheduleUpdateShadow);super.detach(position);detachScrollPositionKey(position as _NestedScrollPosition);_scheduleUpdateShadow();}


void attachScrollPositionKey(_NestedScrollPosition position) {if (position != null && scrollPositionKeyMap != null) {var key = position.setScrollPositionKey();if (key != null) {if (!scrollPositionKeyMap.containsKey(key)) {scrollPositionKeyMap[key] = position;} else if (scrollPositionKeyMap[key] != position) {//in demo ,when tab to tab03, the tab02 key will be tab00 at first//then it become tab02.//this is not a good solution


position.clearScrollPositionKey();Future.delayed(Duration(milliseconds: 500), () {attachScrollPositionKey(position);});}}}}


void detachScrollPositionKey(_NestedScrollPosition position) {if (position != null &&scrollPositionKeyMap != null &&position.key != null &&scrollPositionKeyMap.containsKey(position.key)) {scrollPositionKeyMap.remove(position.key);position.clearScrollPositionKey();}}


获取先祖 NestedScrollViewInnerScrollPositionKeyWidget 方法


Key setScrollPositionKey() {//if (haveDimensions) {final type = _typeOf<NestedScrollViewInnerScrollPositionKeyWidget>();


NestedScrollViewInnerScrollPositionKeyWidget keyWidget =(this.context as ScrollableState)?.context?.ancestorWidgetOfExactType(type);_key = keyWidget?.scrollPositionKey;return _key;}


找到这个_NestedScrollCoordinator 的 applyUserOffset 方法中我们现在要替换掉 _innerPositions 为_currentInnerPositions


Iterable<_NestedScrollPosition> get _innerPositions {//return _currentPositions;return _innerController.nestedPositions;}


Iterable<_NestedScrollPosition> get _currentInnerPositions {return _innerControlle


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


r.getCurrentNestedPositions(innerScrollPositionKeyBuilder);}


getCurrentNestedPositions 里面的代码


Iterable<_NestedScrollPosition> getCurrentNestedPositions(NestedScrollViewInnerScrollPositionKeyBuilderinnerScrollPositionKeyBuilder) {if (innerScrollPositionKeyBuilder != null &&scrollPositionKeyMap.length > 1) {var key = innerScrollPositionKeyBuilder();if (scrollPositionKeyMap.containsKey(key)) {return <_NestedScrollPosition>[scrollPositionKeyMap[key]];} else {return nestedPositions;}}


return nestedPositions;}

SampeCode

extended.NestedScrollView(headerSliverBuilder: (c, f) {return _buildSliverHeader(primaryTabBar);},//pinnedHeaderSliverHeightBuilder: () {return pinnedHeaderHeight;},innerScrollPositionKeyBuilder: () {var index = "Tab";if (primaryTC.index == 0) {index +=(primaryTC.index.toString() + secondaryTC.index.toString());} else {index += primaryTC.index.toString();}return Key(index);},


这里由你自己协定 tab key。。我这里是一级 tab+二级 tab 的 index。。比如 Tab00 代表一级 tab 第一个下面的二级 tab 的第一个。


定义 tab 里面的列表的时候如下,比如第一个 tab 下面的二级 tab 的第一个列表,那么它的 key 为 Tab00.


return extended.NestedScrollViewInnerScrollPositionKeyWidget(Key("Tab00"),// myRefresh.RefreshIndicator(// child:ListView.builder(itemBuilder: (c, i) {return Container(//decoration: BoxDecoration(border: Border.all(color: Colors.orange,width: 1.0)),alignment: Alignment.center,height: 60.0,child: Text(widget.tabKey.toString() + ": List$i"),);},itemCount: 100)//,

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Flutter 扩展NestedScrollView (二)列表滚动同步解决