Skip to content

Commit d3a91e5

Browse files
authored
Merge branch 'master' into feat-nativecomponent-style
2 parents 6d1c4e5 + ba2be25 commit d3a91e5

File tree

1 file changed

+39
-7
lines changed

1 file changed

+39
-7
lines changed

packages/webpack-plugin/lib/runtime/components/react/mpx-scroll-view.tsx

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
194194
white: ['#fff']
195195
}
196196

197+
const isContentSizeChange = useRef(false)
198+
197199
const { refresherContent, otherContent } = getRefresherContent(props.children)
198200
const hasRefresher = refresherContent && refresherEnabled
199201

@@ -379,7 +381,22 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
379381
}
380382

381383
function onContentSizeChange (width: number, height: number) {
382-
scrollOptions.current.contentLength = selectLength({ height, width })
384+
isContentSizeChange.current = true
385+
const newContentLength = selectLength({ height, width })
386+
const oldContentLength = scrollOptions.current.contentLength
387+
scrollOptions.current.contentLength = newContentLength
388+
// 内容高度变化时,Animated.event 的映射可能会有不生效的场景,所以需要手动设置一下 scrollOffset 的值
389+
if (enableSticky && (__mpx_mode__ === 'android' || __mpx_mode__ === 'ios')) {
390+
// 当内容变少时,检查当前滚动位置是否超出新的内容范围
391+
if (newContentLength < oldContentLength) {
392+
const { visibleLength, offset } = scrollOptions.current
393+
const maxOffset = Math.max(0, newContentLength - visibleLength)
394+
// 如果当前滚动位置超出了新的内容范围,调整滚动offset
395+
if (offset > maxOffset && scrollY) {
396+
scrollOffset.setValue(maxOffset)
397+
}
398+
}
399+
}
383400
}
384401

385402
function onLayout (e: LayoutChangeEvent) {
@@ -402,8 +419,9 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
402419

403420
function onScroll (e: NativeSyntheticEvent<NativeScrollEvent>) {
404421
const { bindscroll } = props
405-
const { x: scrollLeft, y: scrollTop } = e.nativeEvent.contentOffset
406-
const { width: scrollWidth, height: scrollHeight } = e.nativeEvent.contentSize
422+
const { contentOffset, layoutMeasurement, contentSize } = e.nativeEvent
423+
const { x: scrollLeft, y: scrollTop } = contentOffset
424+
const { width: scrollWidth, height: scrollHeight } = contentSize
407425
isAtTop.value = scrollTop <= 0
408426
bindscroll &&
409427
bindscroll(
@@ -414,7 +432,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
414432
scrollHeight,
415433
scrollWidth,
416434
deltaX: scrollLeft - scrollOptions.current.scrollLeft,
417-
deltaY: scrollTop - scrollOptions.current.scrollTop
435+
deltaY: scrollTop - scrollOptions.current.scrollTop,
436+
layoutMeasurement
418437
},
419438
layoutRef
420439
}, props)
@@ -429,8 +448,9 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
429448

430449
function onScrollEnd (e: NativeSyntheticEvent<NativeScrollEvent>) {
431450
const { bindscrollend } = props
432-
const { x: scrollLeft, y: scrollTop } = e.nativeEvent.contentOffset
433-
const { width: scrollWidth, height: scrollHeight } = e.nativeEvent.contentSize
451+
const { contentOffset, layoutMeasurement, contentSize } = e.nativeEvent
452+
const { x: scrollLeft, y: scrollTop } = contentOffset
453+
const { width: scrollWidth, height: scrollHeight } = contentSize
434454
isAtTop.value = scrollTop <= 0
435455
bindscrollend &&
436456
bindscrollend(
@@ -439,7 +459,8 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
439459
scrollLeft,
440460
scrollTop,
441461
scrollHeight,
442-
scrollWidth
462+
scrollWidth,
463+
layoutMeasurement
443464
},
444465
layoutRef
445466
}, props)
@@ -494,6 +515,16 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
494515
{
495516
useNativeDriver: true,
496517
listener: (event: NativeSyntheticEvent<NativeScrollEvent>) => {
518+
const y = event.nativeEvent.contentOffset.y || 0
519+
// 内容高度变化时,鸿蒙中 listener 回调通过scrollOffset.__getValue获取值一直等于event.nativeEvent.contentOffset.y,值是正确的,但是无法触发 sticky 动画执行,所以需要手动再 set 一次
520+
if (__mpx_mode__ === 'harmony') {
521+
if (isContentSizeChange.current) {
522+
scrollOffset.setValue(y)
523+
setTimeout(() => {
524+
isContentSizeChange.current = false
525+
}, 100)
526+
}
527+
}
497528
onScroll(event)
498529
}
499530
}
@@ -702,6 +733,7 @@ const _ScrollView = forwardRef<HandlerRef<ScrollView & View, ScrollViewProps>, S
702733
showsVerticalScrollIndicator: scrollY && showScrollbar,
703734
scrollEnabled: !enableScroll ? false : !!(scrollX || scrollY),
704735
bounces: false,
736+
overScrollMode: 'never',
705737
ref: scrollViewRef,
706738
onScroll: enableSticky ? scrollHandler : onScroll,
707739
onContentSizeChange: onContentSizeChange,

0 commit comments

Comments
 (0)