Closed EchoPuda closed 2 years ago
试了下这样改就好了,参照作者自己的文章:https://juejin.cn/post/6997202342655311879
然后改库,在_ExtendedNestedScrollPosition的applyContentDimensions方法,改为:
@override
bool applyContentDimensions(double minScrollExtent, double maxScrollExtent) {
if (debugLabel == 'outer' &&
coordinator.pinnedHeaderSliverHeightBuilder != null) {
maxScrollExtent =
maxScrollExtent - coordinator.pinnedHeaderSliverHeightBuilder!();
maxScrollExtent = math.max(0.0, maxScrollExtent);
}
///新增部分
if (debugLabel == 'inner' && coordinator.pinnedHeaderSliverHeightBuilder != null) {
maxScrollExtent = math.max(maxScrollExtent, 0.1);
}
return super.applyContentDimensions(minScrollExtent, maxScrollExtent);
}
修改可以使用Flutter Aop的方案:https://juejin.cn/post/7036352267389239303
我目前是通过修改 updateCanDrag。观察源码发现控制是否可拖动的决定因素是updateCanDrag。 由于不满屏的maxScrollExtent始终为0,导致inter的updateCanDrag为0,所以在outer的updateCanDrag滚动完毕后,inner不会有滚动的区域,而在上面的情况中,outer的updateCanDrag是小于理应滚动的区域的(因为底部导航导致整体向上的padding,导致max-min实际少于应该滚动的范围)。
@override
void updateCanDrag({_NestedScrollPosition? position}) {
double maxInnerExtent = 0.0;
if (onlyOneScrollInBody &&
position != null &&
position.debugLabel == 'inner') {
if (position.haveDimensions) {
maxInnerExtent = math.max(
maxInnerExtent,
position.maxScrollExtent - position.minScrollExtent,
);
position.updateCanDrag(maxInnerExtent);
}
}
if (!_outerPosition!.haveDimensions) {
return;
}
for (final _NestedScrollPosition position in _innerPositions) {
if (!position.haveDimensions) {
return;
}
maxInnerExtent = math.max(
maxInnerExtent,
position.maxScrollExtent - position.minScrollExtent,
);
}
_outerPosition!.updateCanDrag(maxInnerExtent);
}
}
要达到完整折叠的效果,inner.updateCanDrag + outer.updateCanDrag 应该要大于等于inner的顶部到折叠闭合tab的距离,不然就会卡顿,需要重新识别Drag,也就是第二次拖动才能拖到顶部。
所以我主要是通过修改maxInnerExtent的默认值来实现。使其大于等于顶部折叠tab到屏幕底部的距离(不管底部有什么padding,大于就好)
@override
void updateCanDrag({_NestedScrollPosition? position}) {
double maxInnerExtent = 0;
if (onlyOneScrollInBody &&
position != null &&
position.debugLabel == 'inner') {
if (position.haveDimensions) {
double pinnedHeader = pinnedHeaderSliverHeightBuilder?.call() ?? 0;
maxInnerExtent = MediaQueryData.fromWindow(window).size.height - pinnedHeader;
maxInnerExtent = math.max(
maxInnerExtent,
position.maxScrollExtent - position.minScrollExtent,
);
position.updateCanDrag(maxInnerExtent);
}
}
if (!outerPosition!.haveDimensions) {
return;
}
for (final _NestedScrollPosition position in innerPositions) {
if (!position.haveDimensions) {
return;
}
maxInnerExtent = math.max(
maxInnerExtent,
position.maxScrollExtent - position.minScrollExtent,
);
}
outerPosition!.updateCanDrag(maxInnerExtent);
}
最终就能流畅的滑动折叠展开了。
我会关闭这个issue,但我觉得这个作者是可以考虑优化下这部分的判断的。
试了下这样改就好了,参照作者自己的文章:https://juejin.cn/post/6997202342655311879
然后改库,在_ExtendedNestedScrollPosition的applyContentDimensions方法,改为:
@override bool applyContentDimensions(double minScrollExtent, double maxScrollExtent) { if (debugLabel == 'outer' && coordinator.pinnedHeaderSliverHeightBuilder != null) { maxScrollExtent = maxScrollExtent - coordinator.pinnedHeaderSliverHeightBuilder!(); maxScrollExtent = math.max(0.0, maxScrollExtent); } ///新增部分 if (debugLabel == 'inner' && coordinator.pinnedHeaderSliverHeightBuilder != null) { maxScrollExtent = math.max(maxScrollExtent, 0.1); } return super.applyContentDimensions(minScrollExtent, maxScrollExtent); }
修改可以使用Flutter Aop的方案:https://juejin.cn/post/7036352267389239303
兄弟你能提下代码让作者去合并吗,作者貌似没发现
试了下这样改就好了,参照作者自己的文章:https://juejin.cn/post/6997202342655311879 然后改库,在_ExtendedNestedScrollPosition的applyContentDimensions方法,改为:
@override bool applyContentDimensions(double minScrollExtent, double maxScrollExtent) { if (debugLabel == 'outer' && coordinator.pinnedHeaderSliverHeightBuilder != null) { maxScrollExtent = maxScrollExtent - coordinator.pinnedHeaderSliverHeightBuilder!(); maxScrollExtent = math.max(0.0, maxScrollExtent); } ///新增部分 if (debugLabel == 'inner' && coordinator.pinnedHeaderSliverHeightBuilder != null) { maxScrollExtent = math.max(maxScrollExtent, 0.1); } return super.applyContentDimensions(minScrollExtent, maxScrollExtent); }
修改可以使用Flutter Aop的方案:https://juejin.cn/post/7036352267389239303
兄弟你能提下代码让作者去合并吗,作者貌似没发现
如果你觉得这个方案有效。你可以fork 自己做修改。在没有准确的原理表明或者官方验证之前,不打算merge 这部分代码
@zmtzawqlp 目前就是自己fork了修改。可以考虑检查下吧,我的修改主要是在业务方面去解决,源头没有时间去研究。
使用底部导航栏BottomNavigationBar,在其PageView中使用ExtendedNestedScrollView(), 其中headerSliverBuilder中使用了固定的SliverAppBar,TabBar,和中间的使用SliverToBoxAdapter展示的信息。 在body中使用的普通的滚动布局,如GridView
然后在GridView中内容较少,或无的情况下,向上滑动折叠不连贯,不顺畅,需要两次拖拽才能滑至最顶处,中间的卡住时,向上向下都无法继续滑动,得松手重新触摸。 经对比,官方的滑动不会卡住。在页面中直接使用也不会有这问题。GridView的内容超过一屏左右也不会有问题。 希望能有解决的方法
BottomNavigationBar 为正常的使用方式:
ExtendedNestedScrollView:
GridView: