将数据添加到 FlatList 始终显示第一个孩子
Posted
技术标签:
【中文标题】将数据添加到 FlatList 始终显示第一个孩子【英文标题】:Prepending data to a FlatList always shows the first child 【发布时间】:2019-11-04 13:40:56 【问题描述】:这是我们的 FlatList,打个招呼:
<FlatList
data=this.state.dates
...
/>
我们提供以下日期:
this.state =
dates: [
'21/06/2019',
'22/06/2019',
'23/06/2019',
]
;
那么当可见日期发生变化时(onViewableItemsChanged
),如果我们最终到达第一项(21/06/2019),我们会在前面添加数据,这样新的状态就变成了:
dates: [
'18/06/2019',
'19/06/2019',
'20/06/2019',
'21/06/2019',
'22/06/2019',
'23/06/2019',
]
问题:
在我们预先添加数据之后,我们现在看到的是 2019 年 6 月 19 日。
这是因为在底层,21/06/2019 曾经是索引 0,但在前置后,索引 0 对应于 19/06/2019。
我们想要什么:
我正在努力做到这一点,以便在预置数据后一天保持不变。
请不要告诉我使用scrollToPosition
,因为这确实是一种黑客行为,而不是解决方案。
这个问题有什么好的解决办法吗?
谢谢
【问题讨论】:
因为您要更改索引,所以如果没有scrollToIndex
,我不明白您怎么能做到这一点(或者,这将更加骇人听闻)。如果你的物品高度相同,滚动会很快,你可以使用getItemLayout
优化渲染。
您找到合适的解决方案了吗?我在我的项目中面临同样的问题。
没有,目前还没有
@SudoPlz 你找到解决办法了吗?
不是真的,所以我们最终在 react-native 上创建了自己的列表组件,我试图说服我们的管理层允许我们发布开源代码。
【参考方案1】:
有一个库:https://github.com/GetStream/react-native-bidirectional-infinite-scroll,它允许您预先准备或附加数据并保留滚动位置
它基本上是对 FlatList 的扩展,并支持普通 FlatList 可用的所有道具
来自他们的示例使用教程:https://dev.to/vishalnarkhede/react-native-how-to-build-bidirectional-infinite-scroll-32ph#%F0%9F%96%A5-tutorial-chat-ui-with-bidirectional-infinite-scroll
看起来只需像您尝试做的那样将该数据预先添加到顶部就足够了
【讨论】:
看起来很酷,但不适用于 Expo 管理的工作流程。【参考方案2】:把这个留在这里,因为我花了一段时间才找到一个可行的解决方案/解决这个问题的方法,但不会让我觉得不好:用空数据预填充数组,然后使用 scrollToIndex
方法.
this.state =
dates: [
'',
'',
'',
'21/06/2019',
'22/06/2019',
'23/06/2019',
]
;
然后:
<FlatList
data=this.state.dates
ref=flatListRef
getItemLayout=(data, index) => (
length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index
)
...
/>
在您的 componentDidMount 中:
const startingIndex = 4
flatListRef.current.scrollToIndex(index: startingIndex, animated: false, viewPosition: 0)
【讨论】:
确实如此,但您是否可以预先填充数据的合理数量(例如,您是否希望用户回溯到 2 年以上?)【参考方案3】:如果您在 滚动位置 0(一直到顶部)时预先添加数据,maintainVisibleContentPosition
将不起作用。如果您在 不是顶部 时进行前置,它确实有效。即使滚动 Y of 1 也足够了。
检查this
不幸的是,即使在React Native 0.63.3
中,这仍然是一个问题,并且尚未解决。
【讨论】:
【参考方案4】:ScrollView
上有一个未记录的道具 maintainVisibleContentPosition 可以做你想做的事,但不幸的是它不适用于 android
我找到了另一种解决方法,使用onScroll 保持最新的 y 偏移量,并在使用 onContentSizeChange 添加新项目之前和之后保存内容高度并计算内容高度的差异,并将新的 y 偏移量设置为最新的 y 偏移量 +内容高度差!
我也开了issue on github,但还没有完整的解决方案 感谢 sgtpepper43 提供未记录的 ios 解决方案
【讨论】:
感谢您向我保证,我不是唯一面临该问题的人。看起来有人将不得不深入研究 Android 代码并为 Android 实现该标志。 我在iOS
上测试了maintainVisibleContentPosition
。但是,如果您使用 append
数据,则此属性 only
有效。如果你 prepend
数据,它确实 not
工作。以上是关于将数据添加到 FlatList 始终显示第一个孩子的主要内容,如果未能解决你的问题,请参考以下文章
在 React Native 中动态添加项目到 FlatList