React Native:呈现无限数量的页面(双向刷卡)

时间:2019-01-22 22:59:54

标签: android arrays react-native carousel react-native-android

问题

人们如何实现无数页面以供您动态浏览?

详细信息

如果应用在一天中呈现页面,则可以期望在前一天向右滑动,而在第二天向左滑动。

例如,FitNotes应用程序可以做到这一点: FitNotes app day view

向左/向右滑动与按按钮5/6相同。并显示已经渲染的页面。同时,还会渲染最近几天的新页面。

最初,我认为您可以使用轮播,例如使用react-native-snap-carousel库来完成此操作。我想像下面的示例,但是使用状态变量而不是图像数组来呈现页面。

Example carousel from the react-native-snap-carousel library

因此,如果我想呈现日期在顶部的页面,则将数组作为状态的一部分,例如:

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命令似乎不是一种选择,因为我会在现有状态转换期间进行渲染。.

2 个答案:

答案 0 :(得分:6)

此解决方案基于您提到的react-native-swiper。 如果缓存正确完成,这是一个棘手的解决方案,可以起作用。 它基于以下假设:

  • 给出ID,您可以得出ID + 1和ID-1。 (这对日期有效)
  • 您只能向左或向右滚动1帧(查看)。

这个想法是在<Swiper>周围有一个包装器组件,用于保存具有3个ID(当前,左和右)的状态数组。

state = {
  pages: ["2", "3", "4"],
  key: 1
}

向左或向右滑动时,您可以导出下一个或上一个3个ID,然后调用setStaterender方法将调用本地缓存的信息以获取这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提供足够的缓存信息。如果缓存访问快要结束了,请确保请求新数据并从另一个方向删除一些缓存数据。

这是App.js的PasteBin和一个GitHub项目,因此您可以测试整个想法。

enter image description here

答案 1 :(得分:0)

那很有趣。

我认为还需要对系统设计进行一些更改。让我尝试一点一点地给出答案。

问题1:数组不断增长 您不必在此处使用数组,因为我看到您添加条件的条件是基于日期的。您必须具有日期功能才能减去/加到当前日期,并向服务器调用相同的日期。收到数据后,您需要维护用户缓存,这将有助于您减少通话次数。

,如果您只想坚持使用阵列,则只需要在用户输入项上加载Date+-3数据,并将其仅保留在缓存中(或者,新数据库是一种解决方法,但包括费用)。

问题2:索引编制 a)前置元素:

摆脱阵列时这应该不是问题。您可以使用状态,并且单个对象应该适合您。

b)删除元素

您删除元素的依据是日期,而不是索引。因此,如果您收到日期为Date-1的空响应,然后致电Date-2,并且由于您有3天的限制,则可以禁用对空响应的滑动功能。

OR 如果您只处理数组,则必须执行cron作业,该作业将为您更新数据)

希望有帮助,如果您愿意,我可以提供更详细的信息。