我正在尝试使用 <Flatlist />
在 React Native 中创建一个聊天室。
就像 WhatsApp 和其他聊天应用一样,消息从底部开始显示。
从我的 API 获取消息后,我调用
this.myFlatList.scrollToEnd({animated: false});
但它有时会在中间滚动,有时底部的项目较少,有时什么也不做。
我如何最初将其滚动到底部?
我的聊天消息高度不同,因此无法计算高度。
我正在尝试使用 <Flatlist />
在 React Native 中创建一个聊天室。
就像 WhatsApp 和其他聊天应用一样,消息从底部开始显示。
从我的 API 获取消息后,我调用
this.myFlatList.scrollToEnd({animated: false});
但它有时会在中间滚动,有时底部的项目较少,有时什么也不做。
我如何最初将其滚动到底部?
我的聊天消息高度不同,因此无法计算高度。
我遇到了类似的问题。如果你希望聊天消息从底部开始显示,可以将 "inverted" 设置为 true,然后将你的消息和时间标签以相反的方向显示。
在这里查看 FlatList 的 "inverted" 属性。 https://facebook.github.io/react-native/docs/flatlist#inverted
如果你希望聊天消息从顶部开始显示,这也是我想要实现的。因为像你所说的,高度不同,所以我无法在 FlatList 中找到解决方案。我不能使用 getItemLayout,因为它会使 "scrollToEnd" 以奇怪的方式表现。
我采用了 @My Mai 提到的方法,而是使用 ScrollView,并在 setTimeout 函数中执行 scrollToEnd({animated: false})。此外,我添加了一个状态来隐藏内容,直到 scrollToEnd 完成,这样用户就不会看到任何滚动。
我使用了反转属性和反转函数解决了这个问题
https://facebook.github.io/react-native/docs/flatlist#inverted
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse
<FlatList
inverted
data={[...data].reverse()}
renderItem={renderItem}
keyExtractor={(item) => item.id}
/>
您可以在聊天组件中使用此解决方案。
<Flatlist
data={dataSet}
initialScrollIndex={dataSet.length - 1}
/>
我曾经和你一样遇到了同样的问题,后来我开始使用ScrollView。现在问题解决了:
componentDidMount() {
setTimeout(() => {
this.scrollView.scrollToEnd();
});
}
<ScrollView ref={(ref) => { this.scrollView = ref; }} style={styles.messages}>
{
messages.map((item, i) => (
<Message
key={i}
direction={item.userType === 'banker' ? 'right' : 'left'}
text={item.message}
name={item.name}
time={item.createdAt}
/>
))
}
</ScrollView>`
截至2021年,有两种“好”的解决方案。 第一种是使用timeout、references和useEffect。以下是使用Functional Components和Typescript的完整示例:
// Set the height of every item of the list, to improve perfomance and later use in the getItemLayout
const ITEM_HEIGHT = 100;
// Data that will be displayed in the FlatList
const [data, setData] = React.useState<DataType>();
// The variable that will hold the reference of the FlatList
const flatListRef = React.useRef<FlatList>(null);
// The effect that will always run whenever there's a change to the data
React.useLayoutEffect(() => {
const timeout = setTimeout(() => {
if (flatListRef.current && data && data.length > 0) {
flatListRef.current.scrollToEnd({ animated: true });
}
}, 1000);
return () => {
clearTimeout(timeout);
};
}, [data]);
// Your FlatList component that will receive ref, data and other properties as needed, you also have to use getItemLayout
<FlatList
data={data}
ref={flatListRef}
getItemLayout={(data, index) => {
return { length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index };
}}
{ ...otherProperties }
/>
通过上面的示例,您可以实现流畅而有动画效果的滚动到底部。例如,在接收新消息并需要滚动到底部时推荐使用。
除此之外,第二种更简单的方法是通过实现initialScrollIndex
属性,该属性将立即在底部加载列表,就像您提到的聊天应用程序一样。当首次打开聊天屏幕时,它将正常工作。
像这样:
// No need to use useEffect, timeout and references...
// Just use getItemLayout and initialScrollIndex.
// Set the height of every item of the list, to improve perfomance and later use in the getItemLayout
const ITEM_HEIGHT = 100;
<FlatList
data={data}
getItemLayout={(data, index) => {
return { length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index };
}}
{ ...otherProperties }
/>
我找到了一个对我百分之百有效的解决方案。
在我的平面列表中添加了引用flatListRef
:
<Flatlist
reference={(ref) => this.flatListRef = ref}
data={data}
keyExtractor={keyExtractor}
renderItem={renderItem}
/>
当你想要自动滚动到列表底部时,请使用以下方法:
this.flatListRef._listRef._scrollRef.scrollToEnd({ animating: true });
是的,您应该访问元素 _listRef,然后访问 _scrollRef,最后调用 scrollToEnd。
let scrollRef = React.useRef(null)
并且
<FlatList
ref={(it) => (scrollRef.current = it)}
onContentSizeChange={() =>
scrollRef.current?.scrollToEnd({animated: false})
}
data={data}/>
使用 inverted={1} 并使用 JS反转函数 反转您的数据。这对我有用。
我也曾为此苦恼,但是我找到了对我来说最好的解决方案,没有任何故障:
inverted={-1}
属性data={this.state.messages.reverse()}
中的 data={MyArrayofMessages.reverse()}
。非常简单,瞬间呈现!
这段代码是关于编程的,它用于创建一个名为FlatList的组件,并设置了contentContainerStyle属性。该属性中包含了一个flex属性和一个justifyContent属性,用于控制组件的布局和对齐方式。<FlatList contentContainerStyle={{ flex: 1, justifyContent: 'flex-end' }} />
flex-direction
改为column-reverse。现在它按预期工作:<FlatList data={messages} inverted contentContainerStyle={{ flexDirection: 'column-reverse' }} />
- Johnny FeketeflexDirection: 'column-reverse'
引起的。相反,在数据数组中调用reverse()
虽然不是最佳性能,但似乎是没有故障的解决方案。 - fermmm