问题
人们如何实现无数页面以供您动态浏览?
详细信息
如果应用在一天中呈现页面,则可以期望在前一天向右滑动,而在第二天向左滑动。
向左/向右滑动与按按钮5/6相同。并显示已经渲染的页面。同时,还会渲染最近几天的新页面。
最初,我认为您可以使用轮播,例如使用react-native-snap-carousel库来完成此操作。我想像下面的示例,但是使用状态变量而不是图像数组来呈现页面。
因此,如果我想呈现日期在顶部的页面,则将数组作为状态的一部分,例如:
carouselElements: [ '2019/01/21', '2019/01/22', '2019/01/23']
放到下面的轮播中,我将返回三页,每页的顶部显示日期。
<Carousel
ref={(c) => { this._carousel = c; }}
data={this.props.carouselElements}
renderItem={this.renderDay}
sliderWidth={sliderWidth}
itemWidth={sliderWidth}
enableSnap
firstItem={1}
initialNumToRender={3}
maxToRenderPerBatch={3}
onBeforeSnapToItem={(index) => this.changeEvent(index)}
useScrollView/>
问题1:数组不断增长
您可以从Day X
开始,并提前两天进行渲染。
如果我向左滑动,则访问Day X+1
并将concat Day X+2
连接到数组的末尾并也渲染该天。
该数组变为:
[ 'Day X-1', 'Day X', 'Day X+1', 'Day X+2']
为了提高性能,我可以继续在3天的时间范围内检查索引,并仅呈现所选的日期和相邻的两天。但是数组将无限增长,并且您的代码最多为O(n)。
问题2:建立索引
a)前置元素:
您可以从Day X
开始,然后向右滑动。您现在正在显示Day X-1
。您将Day X-2
添加到数组的开头并进行渲染,以准备向右再次滑动。问题是您在索引0处添加了一个元素。当系统从Day X-1
更改为Day X-2
时,系统指向索引0的状态,因此该页面现在显示Day X-2
。 / p>
即,当您向右滑动时,并没有向后移动一天,而是每次滑动都向后移动了2天。
b)删除元素
如果我删除一个元素以保持数组较小,则所有内容都会移动,但索引保持不变。现在,索引指向与数组中预期元素不同的元素,这会在呈现页面中反映出来,然后才能更正索引。
我的问题 人们如何通过页面滑动无限地实现动态页面呈现广告?似乎很多应用程序都拥有它,我找不到任何谈论它的人。
编辑1:添加了带有伴随修改的图片,以更好地解释我的问题。
编辑2:我有一个react-native-swiper可行的实现方式,该实现方式基本上需要一个大型数组,并且仅呈现与显示页面紧邻的那批幻灯片。
<Swiper style={styles.wrapper}
showsButtons={false}
index={currentDateIndex}
loadMinimal={true}
loadMinimalSize={1}
showsPagination={false}
loop={false}
onIndexChanged={(index) => dispatch(changeSelectedDayByIndex(index))}
>
{dates.map((item) =>
this.renderDay(item)
)
}
</Swiper>
但是,dates.map
命令在启动时会造成很大的性能损失。
编辑3:
映射之前在dates数组上使用slice
命令似乎不是一种选择,因为我会在现有状态转换期间进行渲染。.
答案 0 :(得分:6)
此解决方案基于您提到的react-native-swiper
。
如果缓存正确完成,这是一个棘手的解决方案,可以起作用。
它基于以下假设:
这个想法是在<Swiper>
周围有一个包装器组件,用于保存具有3个ID(当前,左和右)的状态数组。
state = {
pages: ["2", "3", "4"],
key: 1
}
向左或向右滑动时,您可以导出下一个或上一个3个ID,然后调用setState
。 render
方法将调用本地缓存的信息以获取这3个ID的视图属性并呈现新的Screen。 <Swiper>
元素始终必须指向index={1}
作为初始参数,并保持这种方式。
const cache = {
"0": "zero",
"1": "one",
"2": "two",
"3": "three",
"4": "four",
"5": "five",
"6": "six",
"7": "seven",
"8": "eight",
"9": "nine",
"10": "ten"
}
renderItem(item, idx) {
const itemInt = parseInt(item)
const style = itemInt % 2 == 0 ? styles.slide1 : styles.slide2
return (
<View style={style} key={idx}>
<Text style={styles.text}>{cache[item]}</Text>
</View>
)
}
但是,当您滑动时,它将当前索引设置为2或0。因此,为了使其始终指向索引1(同样,因为您已移动并重新加载),必须强制{{1 }}元素以重新加载。您可以通过将其key属性设置为始终变化的状态变量来实现。那是棘手的部分。
<Swiper>
除此之外,还必须确保始终为ID提供足够的缓存信息。如果缓存访问快要结束了,请确保请求新数据并从另一个方向删除一些缓存数据。
答案 1 :(得分:0)
那很有趣。
我认为还需要对系统设计进行一些更改。让我尝试一点一点地给出答案。
问题1:数组不断增长 您不必在此处使用数组,因为我看到您添加条件的条件是基于日期的。您必须具有日期功能才能减去/加到当前日期,并向服务器调用相同的日期。收到数据后,您需要维护用户缓存,这将有助于您减少通话次数。
或,如果您只想坚持使用阵列,则只需要在用户输入项上加载Date+-3
数据,并将其仅保留在缓存中(或者,新数据库是一种解决方法,但包括费用)。
问题2:索引编制 a)前置元素:
摆脱阵列时这应该不是问题。您可以使用状态,并且单个对象应该适合您。
b)删除元素
您删除元素的依据是日期,而不是索引。因此,如果您收到日期为Date-1
的空响应,然后致电Date-2
,并且由于您有3天的限制,则可以禁用对空响应的滑动功能。
( OR 如果您只处理数组,则必须执行cron作业,该作业将为您更新数据)
希望有帮助,如果您愿意,我可以提供更详细的信息。