反应本机平面列表初始滚动到底部
React native flatlist initial scroll to bottom
我正在尝试使用 <Flatlist />
在 React Native 中创建聊天
与 WhatsApp 和其他聊天应用程序一样,消息从底部开始。
从我的 API 获取消息后,我调用
this.myFlatList.scrollToEnd({animated: false});
但它会在中间某处滚动,有时滚动到底部的项目较少,有时什么也不做。
我怎样才能开始滚动到底部?
我的聊天消息有不同的高度,所以我无法计算高度。
我猜 RN 无法猜出你的布局,所以它不知道它需要多少 "move"。根据文档中的滚动方法,您可能需要实现一个 getItemLayout 函数,以便 RN 可以知道它需要滚动多少。
https://facebook.github.io/react-native/docs/flatlist.html#scrolltoend
我遇到了与您相同的问题,然后我转而使用 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>`
我有类似的问题。如果你想让你的聊天消息从底部开始,你可以将 "inverted" 设置为 true 并在相反的方向显示你的消息和时间标签。
在此处检查 "inverted" 属性 FlatList。 https://facebook.github.io/react-native/docs/flatlist#inverted
如果你想让你的聊天消息从顶部开始,这就是我想要实现的。我无法在 FlatList 中找到解决方案,因为正如您所说,高度不同,我无法使用 getItemLayout,这使得 "scrollToEnd" 行为异常。
我按照@My Mai 提到的方法,改用 ScrollView 并在 setTimeout 函数中执行 scrollToEnd({animated: false}) 。此外,我添加了一个状态来隐藏内容,直到 scrollToEnd 完成,这样用户就不会看到任何滚动。
将 initialScrollIndex
设置为数据集的长度 - 1。
即
<Flatlist
data={dataSet}
initialScrollIndex={dataSet.length - 1}
/>
伙计们,如果你想让 FlatList 在初始渲染时滚动到底部。刚刚将 inverted={-1} 添加到您的 FlatList。我努力滚动到底部几个小时,但最终以 inverted={-1} 结束。无需考虑使用 getItemLayout 和 initialScrollIndex 或其他任何方式动态测量 FlatList 项目的高度。
<FlatList contentContainerStyle={{ flex: 1, justifyContent: 'flex-end' }} />
我也在这方面苦苦挣扎,并找到了对我来说渲染无故障的最佳解决方案是:
- 使用
inverted={-1}
道具
- 在我的例子中
data={this.state.messages.reverse()}
使用 reverse() javascript 函数 data={MyArrayofMessages.reverse()}
反转数组中消息对象的顺序。
非常简单,瞬间呈现!
使用 inverted={1} 并使用 JS 反转函数 反转数据。它对我有用
如果要反转显示消息,请在平面列表中将“inverted”设置为true。
<Flatlist
data={messageData}
inverted={true}
horizontal={false}
/>
如果只想滚动到最后一条消息,可以使用 initialScrollIndex
<Flatlist
data={messageData}
initialScrollIndex={messageArray.length - 1}
horizontal={false}
/>
我找到了 100% 适合我的解决方案
将参考 flatListRef
添加到我的平面列表中:
<Flatlist
reference={(ref) => this.flatListRef = ref}
data={data}
keyExtractor={keyExtractor}
renderItem={renderItem}
/>
然后,每当您想自动滚动到列表底部时,请使用:
this.flatListRef._listRef._scrollRef.scrollToEnd({ animating: true });
是的,您应该访问元素 _listRef 然后 _scrollRef 然后调用 scrollToEnd
- react-native 0.64.1
- 反应 17.0.2
截至 2021 年,有两种 'good' 解决方案。
第一个是超时、引用和 useEffect。这是使用功能组件和 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 }
/>
我用反转 属性 和反向函数
解决了这个问题
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
包裹在 View
中,将 FlatList
设置为反转,使其占用所有可用的 space 然后合理的内容。所以现在,消息很少的对话从顶部开始,但当有多个消息时,它们将在底部结束。像这样:
<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'
}
};
我找到了 100% 适合我的解决方案
let scrollRef = React.useRef(null)
和
<FlatList
ref={(it) => (scrollRef.current = it)}
onContentSizeChange={() =>
scrollRef.current?.scrollToEnd({animated: false})
}
data={data}/>
我正在尝试使用 <Flatlist />
与 WhatsApp 和其他聊天应用程序一样,消息从底部开始。
从我的 API 获取消息后,我调用
this.myFlatList.scrollToEnd({animated: false});
但它会在中间某处滚动,有时滚动到底部的项目较少,有时什么也不做。
我怎样才能开始滚动到底部?
我的聊天消息有不同的高度,所以我无法计算高度。
我猜 RN 无法猜出你的布局,所以它不知道它需要多少 "move"。根据文档中的滚动方法,您可能需要实现一个 getItemLayout 函数,以便 RN 可以知道它需要滚动多少。
https://facebook.github.io/react-native/docs/flatlist.html#scrolltoend
我遇到了与您相同的问题,然后我转而使用 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>`
我有类似的问题。如果你想让你的聊天消息从底部开始,你可以将 "inverted" 设置为 true 并在相反的方向显示你的消息和时间标签。
在此处检查 "inverted" 属性 FlatList。 https://facebook.github.io/react-native/docs/flatlist#inverted
如果你想让你的聊天消息从顶部开始,这就是我想要实现的。我无法在 FlatList 中找到解决方案,因为正如您所说,高度不同,我无法使用 getItemLayout,这使得 "scrollToEnd" 行为异常。
我按照@My Mai 提到的方法,改用 ScrollView 并在 setTimeout 函数中执行 scrollToEnd({animated: false}) 。此外,我添加了一个状态来隐藏内容,直到 scrollToEnd 完成,这样用户就不会看到任何滚动。
将 initialScrollIndex
设置为数据集的长度 - 1。
即
<Flatlist
data={dataSet}
initialScrollIndex={dataSet.length - 1}
/>
伙计们,如果你想让 FlatList 在初始渲染时滚动到底部。刚刚将 inverted={-1} 添加到您的 FlatList。我努力滚动到底部几个小时,但最终以 inverted={-1} 结束。无需考虑使用 getItemLayout 和 initialScrollIndex 或其他任何方式动态测量 FlatList 项目的高度。
<FlatList contentContainerStyle={{ flex: 1, justifyContent: 'flex-end' }} />
我也在这方面苦苦挣扎,并找到了对我来说渲染无故障的最佳解决方案是:
- 使用
inverted={-1}
道具 - 在我的例子中
data={this.state.messages.reverse()}
使用 reverse() javascript 函数data={MyArrayofMessages.reverse()}
反转数组中消息对象的顺序。
非常简单,瞬间呈现!
使用 inverted={1} 并使用 JS 反转函数 反转数据。它对我有用
如果要反转显示消息,请在平面列表中将“inverted”设置为true。
<Flatlist
data={messageData}
inverted={true}
horizontal={false}
/>
如果只想滚动到最后一条消息,可以使用 initialScrollIndex
<Flatlist
data={messageData}
initialScrollIndex={messageArray.length - 1}
horizontal={false}
/>
我找到了 100% 适合我的解决方案
将参考 flatListRef
添加到我的平面列表中:
<Flatlist
reference={(ref) => this.flatListRef = ref}
data={data}
keyExtractor={keyExtractor}
renderItem={renderItem}
/>
然后,每当您想自动滚动到列表底部时,请使用:
this.flatListRef._listRef._scrollRef.scrollToEnd({ animating: true });
是的,您应该访问元素 _listRef 然后 _scrollRef 然后调用 scrollToEnd
- react-native 0.64.1
- 反应 17.0.2
截至 2021 年,有两种 'good' 解决方案。 第一个是超时、引用和 useEffect。这是使用功能组件和 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 }
/>
我用反转 属性 和反向函数
解决了这个问题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
包裹在 View
中,将 FlatList
设置为反转,使其占用所有可用的 space 然后合理的内容。所以现在,消息很少的对话从顶部开始,但当有多个消息时,它们将在底部结束。像这样:
<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'
}
};
我找到了 100% 适合我的解决方案
let scrollRef = React.useRef(null)
和
<FlatList
ref={(it) => (scrollRef.current = it)}
onContentSizeChange={() =>
scrollRef.current?.scrollToEnd({animated: false})
}
data={data}/>