-
-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
消息内部有折叠、展开的时候消息位置固定,当展开的内容很长的时候 standby 位置固定无效 #112
Comments
问题的原因与 #111 (comment) 一致,请适度控制消息的长度或者 另外一些优化:
请升级至 void expandCb(int index) {
final isLastItem = index == messages.length - 1;
// 默认是对比上一个 item 来定位
// 最后一个 item,没有上一个可以对比,则对比自身
// 此处对比自身无意义,因为由 customAdjustPosition 去完全控制保持位置的计算,忽略即可。
final refItemIndex = isLastItem ? index : index + 1;
chatObserver.standby(
mode: ChatScrollObserverHandleMode.specified,
refIndexType: ChatScrollObserverRefIndexType.itemIndex,
refItemIndex: refItemIndex,
refItemIndexAfterUpdate: refItemIndex,
customAdjustPosition: (model) {
// 仅处理最后一个 item 的情况
if (!isLastItem) return null;
// 使用 变化前后的底部间距差 来保持位置
final delta =
model.newPosition.extentAfter - model.oldPosition.extentAfter;
return model.adjustPosition + delta;
},
customAdjustPositionDelta: (model) {
// 仅处理不是最后一个 item 的情况
if (isLastItem) return null;
// 以 变化前后的 item 偏移差 来保持位置
final adjustPosition = model.adjustPosition;
final delta = model.currentItemModel.layoutOffset -
model.observer.refItemLayoutOffset;
if (delta < 0) {
// 收起
// 因消息的高度太大,在收起时,Flutter 内部对列表的偏移计算有问题
// 所以这里调整计算方式,改为:视口的当前偏移量 - 内容变化量
// 注:减去 adjustPosition,是因为保持位置功能的内部会加上 adjustPosition
return model.currentItemModel.viewportPixels + delta - adjustPosition;
}
// 展开
return delta;
},
);
} |
感谢!按照以上方式解决了我的问题。 |
|
// Customize the adjustPosition. | |
double? customAdjustPosition = observer.customAdjustPosition?.call( | |
ChatScrollObserverCustomAdjustPositionModel( | |
oldPosition: oldPosition, | |
newPosition: newPosition, | |
isScrolling: isScrolling, | |
velocity: velocity, | |
adjustPosition: adjustPosition, | |
observer: observer, | |
), | |
); | |
if (customAdjustPosition != null) { | |
_handlePositionCallback(ChatScrollObserverHandlePositionResultModel( | |
type: ChatScrollObserverHandlePositionType.keepPosition, | |
mode: observer.innerMode, | |
changeCount: observer.changeCount, | |
)); | |
return customAdjustPosition; | |
} |
如你的示例代码中的最后一个 item
,当其高度发生变化时无可参照 item
,但是视口底部距离 (extentAfter )
是变化的,且知道差值是多少,这个时候就得使用使用 customAdjustPosition
回调来自定义列表视图新的偏移量,以达到保持位置的效果。
customAdjustPositionDelta
- 被调用的前提:
- 当前列表视图满足需要保持位置的条件
- 有参照
item
且被渲染
- 作用:用于在列表视图新的偏移量的基本上做调整,一般在有参照
item
的情况下使用
flutter_scrollview_observer/lib/src/utils/src/chat/chat_observer_scroll_physics_mixin.dart
Lines 61 to 98 in 4f7b653
final model = observer.observeRefItem(); | |
if (model == null) { | |
_handlePositionCallback(ChatScrollObserverHandlePositionResultModel( | |
type: ChatScrollObserverHandlePositionType.none, | |
mode: observer.innerMode, | |
changeCount: observer.changeCount, | |
)); | |
return adjustPosition; | |
} | |
_handlePositionCallback(ChatScrollObserverHandlePositionResultModel( | |
type: ChatScrollObserverHandlePositionType.keepPosition, | |
mode: observer.innerMode, | |
changeCount: observer.changeCount, | |
)); | |
// Customize the delta of the adjustPosition. | |
double? customDelta = observer.customAdjustPositionDelta?.call( | |
ChatScrollObserverCustomAdjustPositionDeltaModel( | |
oldPosition: oldPosition, | |
newPosition: newPosition, | |
isScrolling: isScrolling, | |
velocity: velocity, | |
adjustPosition: adjustPosition, | |
observer: observer, | |
currentItemModel: model, | |
), | |
); | |
// Calculate the final delta. | |
// | |
// If the customDelta is not null, use the customDelta. | |
// Otherwise, use the layoutOffset minus innerRefItemLayoutOffset to get | |
// the difference in the leading offset of the item. | |
final delta = | |
customDelta ?? (model.layoutOffset - observer.innerRefItemLayoutOffset); | |
return adjustPosition + delta; |
该回调在 #103 中被加入,允许在新偏移量的基础上去调整以达到保持位置的功能,返回 null
则按库中逻辑走,使用上可以看之前的例子 #103 (comment) 。
在上述代码中用来处理收起时 adjustPosition
计算异常的情况,当然,你可以继续选择 customAdjustPosition
,看个人喜好了。
注:上述代码中 model.adjustPosition
是 Flutter
内部计算出来的列表视图的新偏移量。
大佬你好,我按照
Originally posted by @wksmile in #103 的方法确实能实现展开位置固定,但是有一个问题,就是当展开的内容很长超过一屏的时候展开收起位置就不能固定了。
如图,展开很长位置固定失效。
写个一个 demo 问题复现代码如下:
scroll_list_page.dart 文件
expand_item.dart 文件
The text was updated successfully, but these errors were encountered: