@@ -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