我正在尝试使用 <Flatlist />
在 React Native 中创建一个聊天室。
就像 WhatsApp 和其他聊天应用一样,消息从底部开始显示。
从我的 API 获取消息后,我调用
this.myFlatList.scrollToEnd({animated: false});
但它有时会在中间滚动,有时底部的项目较少,有时什么也不做。
我如何最初将其滚动到底部?
我的聊天消息高度不同,因此无法计算高度。
我正在尝试使用 <Flatlist />
在 React Native 中创建一个聊天室。
就像 WhatsApp 和其他聊天应用一样,消息从底部开始显示。
从我的 API 获取消息后,我调用
this.myFlatList.scrollToEnd({animated: false});
但它有时会在中间滚动,有时底部的项目较少,有时什么也不做。
我如何最初将其滚动到底部?
我的聊天消息高度不同,因此无法计算高度。
如果你想让FlatList在初始渲染时滚动到底部,只需将inverted={-1}添加到你的FlatList中。我曾经为了让FlatList滚动到底部而苦苦挣扎了几个小时,但最终发现只需要使用inverted={-1}即可。不需要考虑使用getItemLayout和initialScrollIndex等方法来动态地测量FlatList项的高度。
/>
这种方法对我很有效,目前仍在使用。感谢@arjantin。##标题##
我猜测RN无法猜测您的布局,因此它无法知道需要“移动”多少。根据文档中的滚动方法,您可能需要实现一个getItemLayout函数,以便RN可以告诉它需要滚动多少。
https://facebook.github.io/react-native/docs/flatlist.html#scrolltoend
setTimeout
来解决了这个问题。const ChatBoxList: FC = () => {
const listRef = useRef<FlatList<MessageType>>(null);
const [messages, setMessages] = useState<Array<MessageType>>([]);
const onAddNewItem = (newItem: MessageType) => {
setMessages(newItem);
//...
setTimeout(() => {
listRef.current?.scrollToEnd({ animated: true });
}, 100);
};
return (
<FlatList
ref={listRef}
//...
/>
);
}
<Flatlist
data={messageData}
inverted={true}
horizontal={false}
/>
如果你只想滚动到最后一条消息,可以使用initialScrollIndex
<Flatlist
data={messageData}
initialScrollIndex={messageArray.length - 1}
horizontal={false}
/>
inverted
特性在聊天消息中无法使用。 - Baris Senyerli我花了几个小时努力地尝试在不计算包含链接和消息的项目高度的情况下将第一条消息显示在顶部。但最终我成功了...
我的做法是将FlatList
包装在一个View
中,将FlatList
设置为倒置,使其占用所有可用空间,然后调整内容。现在,只有几条消息的对话从顶部开始,但当有多条消息时,它们将结束在底部。就像这样:
<View style={ConversationStyle.container}>
<FlatList
data={conversations}
initialNumToRender={10}
renderItem={({ item }) => (
<SmsConversationItem
item={item}
onDelete={onDelete}
/>
)}
keyExtractor={(item) => item.id}
getItemCount={getItemCount}
getItem={getItem}
contentContainerStyle={ConversationStyle.virtualizedListContainer}
inverted // This will make items in reversed order but will make all of them start from bottom
/>
</View>
我的样式看起来像这样:
const ConversationStyle = StyleSheet.create({
container: {
flex: 1
},
virtualizedListContainer: {
flexGrow: 1,
justifyContent: 'flex-end'
}
};