React Native中ScorllView嵌套的处理。

众所周知:FlatList 是基于 ScrollView 封装的,底层都是 VirtualizedList 组件。安卓端是有提示的:ScrollView和FlatList是禁止嵌套的。

先上布局,最终做出来的显示页面如下:

 

 

 简单分析下布局:整个页面是可以下拉刷新的,日历是吸顶的一个横向可滚动的FlatList,下面内容区域:左侧是可滚动的列表,右侧也是可滚动的列表。右侧滚动下拉时,如果是触顶了,也可以触发整个页面的下拉刷新。右侧列表的顶部又是一小块可横向滚动的标签列表。

刚接到这个稿子是崩溃的,试了很多方案都不行,特别是在安卓机器上,低端安卓机上挺让人崩溃的。此处忽略尝试过的N种方案(尝试过很多用定位的方案)

本方案的核心绊脚石是页面的下拉刷新,难就难在这,由于它的存在,导致了滚动容器必须内外嵌套。

 

直接说下最终的处理方案:安卓上实在是难以兼容各种低端机型,下拉刷新直接放右上角点击刷新(有点蠢),ios上的布局处理,页面最外层用的是ScrollView,内部左侧和右侧都是用的ScrollView组件。

页面最外层的scrollEnabled 通过变量来控制,当内部左侧或者右侧滚动容器触顶的时候,把变量开关打开,则外侧容易可滚动,下拉结束之后立刻关闭变量。

 

<ScrollView
    scrollEnabled={flatListScrollEnable}
    bounces={true}
    alwaysBounceVertical={false}
    style={styles.flatWrap}
    refreshControl={<ZTRefreshControl
       ref={ref => this.innerModel._refreshControl = ref}
       refreshing={isRefreshing}
       onRefresh={() => {
         this.onRefresh()
       }}
       stateLabelColor={'#fff'}
       loadingStyleName={"white"}
    />}
    showsVerticalScrollIndicator={false}
    keyExtractor={(item, index) => index.toString()}
    stickyHeaderIndices={[0]}
    scrollEventThrottle={1}
    onMomentumScrollEnd={(event) => {
         if (flatListScrollEnable) {
            setState({ flatListScrollEnable: false })
         }
    }}
 >
    {/* 左侧列表 */}
    <ScrollView
         bounces={isIos}
         onScroll={() => {
            Animated.event(
               [{}],
               {
                  listener: (event) => {
                      const yOffset = event?.nativeEvent?.contentOffset?.y;
                      if (yOffset <= 1) {
                          if (!flatListScrollEnable) {
                              scrollEnable()
                          }
                      } else {
                           if (flatListScrollEnable) {
                              scrollInhibit()
                      }
                   }
                 }
              })
          }}
          style={styles.scrollWrap}
          showsVerticalScrollIndicator={false}
       >
      {/* 内容列表 */}
  </ScrollView >
   {/* 右侧也如此 */}
   <ScrollView
        bounces={isIos}
        onScroll={() => {
            Animated.event(
                 [{}],
            {
           listener: (event) => {
                  const yOffset = event?.nativeEvent?.contentOffset?.y;
                  if (yOffset <= 1) {
                      if (!flatListScrollEnable) {
                          scrollEnable()
                      }
                  } else {
                      if (flatListScrollEnable) {
                          scrollInhibit()
                  }
               }
            }
           })
        }}
        style={styles.scrollWrap}
        showsVerticalScrollIndicator={false}
   >
       {/* 内容列表 */}
     </ScrollView >
 </ScrollView>

  

也曾尝试过通过监听手势来处理,但是触顶之后的弹性根本不会触发手势响应。很是令人头疼,以上方案也是自己琢磨尝试出来的结果。

该页面为 ios app 智行火车票 智慧出行搜索结果页。

如果您有更好的处理这类布局的方案,还请不吝赐教!

 

posted @ 2020-12-18 14:33  萝卜爱吃青菜  阅读(1440)  评论(0编辑  收藏  举报