在 React-Native 的 ScrollView 中加载新消息时如何保持原位?

How to stay in position when new messages are loaded in a ScrollView in React-Native?

我在聊天应用程序中有一个包含消息的 ScrollView(最近的消息更远)。

我限制了预加载消息的数量,当滚动视图滚动到顶部时,我动态加载了一批新消息。所以当有新消息加载时,当前scrollPos为0.

问题是当新消息到达时,scrollPos 保持为 0,因此用户被传送到最旧的新加载消息。

我尝试通过手动向下滚动到使用内容变化大小的位置来处理它,但这并不令人满意,因为用户看到来回滚动。

有人能想出一种方法来做到这一点,以便用户在新消息出现时看不到任何变化,只需逐渐向上滚动即可看到它们。

只要检测到内容大小发生变化,您就可以使用 onContentSizeChange 属性滚动到底部。

scrollToEnd 功能可能因 RN 版本而异。

<ScrollView
  ...
  onContentSizeChange={() => this.scrollView.scrollToEnd({animated: true})}>
</ScrollView>

参考:https://reactnative.dev/docs/scrollview#scrolltoend

我找到了一种方法。 这个想法来自 Invertible Scroll View 组件:https://github.com/expo/react-native-invertible-scroll-view

我没有使用该组件,而是直接在滚动视图上实现了这个想法,以便对我的代码进行最少的更改。

为了解释,我们使用滚动视图的样式垂直平移滚动视图并进行转换:[{ scaleY: -1 }]。我们对 children 做同样的事情。然后,我们恢复消息的顺序。

在该设置中,scrollPos() 从视觉底部开始测量。为了触发新消息的加载,我现在使用

const isCloseToBottom = ({layoutMeasurement, contentOffset, contentSize}) => {
  const paddingToBottom = 20;
  return layoutMeasurement.height + contentOffset.y >=
    contentSize.height - paddingToBottom;
};

诀窍是现在,当新消息出现在顶部时,您无需做任何事情,因为从用户的角度到底部的距离不会改变。