ScrollView 反弹的 2 种不同背景颜色

2 Different Background Colours For ScrollView bounce

我有一个 ScrollView,它的顶部有一种背景颜色,底部有另一种不同的颜色。

当用户滚动过内容并且视图跳动(弹性过度扩展)时,我怎样才能使背景与顶部或底部一致,具体取决于滚动方向?

在 iOS 上,您可以在 ScrollView 上渲染一个间隔 View,然后使用 contentInset 渲染它 "off-screen",contentOffset 设置初始滚动位置以偏移插入:

render() {
  const isIos = Platform.OS === 'ios'
  const SPACER_SIZE = 1000; //arbitrary size
  const TOP_COLOR = 'white';
  const BOTTOM_COLOR = 'papayawhip';
  return (
    <ScrollView
      style={{backgroundColor: isIos ? BOTTOM_COLOR : TOP_COLOR }}
      contentContainerStyle={{backgroundColor: TOP_COLOR}}
      contentInset={{top: -SPACER_SIZE}}
      contentOffset={{y: SPACER_SIZE}}>

      {isIos && <View style={{height: SPACER_SIZE}} />}
      //...your content here

    </ScrollView>
  );
}

因为 contentInsetcontentOffsetiOS,此示例条件为在 Android 上正常降级。

我不会玩 ScrollView 的 contentInsetcontentOffset,因为如果您的内容发生变化,它可能会改变滚动视图的位置。

只需在 ScrollView 的最顶部添加一个 View,您就可以做一些非常简单的事情:

// const spacerHeight = 1000;

<ScrollView>
  {Platform.OS === 'ios' && (
    <View 
      style={{
        backgroundColor: 'red',
        height: spacerHeight,
        position: 'absolute',
        top: -spacerHeight,
        left: 0,
        right: 0,
      }} 
    />
  )}
</ScrollView>

接受的解决方案对我来说效果不佳,因为我需要将 flexGrow: 1 放在 contentContainerStyle 上。使用 insets/offsets 并没有使内容按照我想要的方式增长,否则效果还不错。

我有另一个解决方案建议:将双色背景层放在透明的 ScrollView 下,并为您的 scrollview 内容添加颜色。这样,在 ios 弹跳时,滚动视图下的双色层将自行显示。

我这里说的是双色层(这里scrollview是空透明的)

现在,如果我放回 ScrollView 子项(如果主体为空白背景,页脚为黄色背景),我会得到:

只要弹跳不超过滚动视图高度的 50%,您就会看到合适的背景颜色。

这是一个可用于包装滚动视图的组件。

const AppScrollViewIOSBounceColorsWrapper = ({
  topBounceColor,
  bottomBounceColor,
  children,
  ...props
}) => {
  return (
    <View {...props} style={[{ position: 'relative' }, props.style]}>
      {children}
      <View
        style={{
          position: 'absolute',
          top: 0,
          left: 0,
          width: '100%',
          height: '100%',
          zIndex: -1, // appear under the scrollview
        }}
      >
        <View
          style={{ flex: 1, backgroundColor: topBounceColor }}
        />
        <View
          style={{ flex: 1, backgroundColor: bottomBounceColor }}
        />
      </View>
    </View>
  );
};

下面是你如何使用它:

  <AppScrollViewIOSBounceColorsWrapper
    style={{flex: 1}}
    topBounceColor="white"
    bottomBounceColor="yellowLancey"
  >
    <ScrollView style={{flex: 1}}>
      <WhiteBackgroundBody/>
      <YellowBackgroundFooter />
    </AppScrollView>
  </AppScrollViewIOSBounceColorsWrapper>

确保不要为滚动视图设置背景颜色,否则双色层将永远不会显示自己(contentContainerStyle 上的 backgroundColor 很好)

对我来说,最简单的解决方案是根据 答案进行修改,不包括换行,只需在 ScrollView 组件之前(或之后)调用它:

创建组件:

interface IScrollViewBackgroundLayer {
  topBounceColor: string;
  bottomBounceColor: string;
}

export const ScrollViewBackgroundLayer = ({
  topBounceColor,
  bottomBounceColor,
}: IScrollViewBackgroundLayer): ReactElement => (
  <View
    style={{
      position: 'absolute',
      top: 0,
      left: 0,
      width: '100%',
      height: '100%',
      zIndex: -1, // appear under the scrollview
    }}>
    <View style={{ flex: 1, backgroundColor: topBounceColor }} />
    <View style={{ flex: 1, backgroundColor: bottomBounceColor }} />
  </View>
);

并像这样使用它:

  return (
    <SafeAreaView style={styles.container}>
      <ScrollViewBackgroundLayer topBounceColor={topBounceColor} bottomBounceColor={bottomBounceColor} />
      <ScrollView>
       ...
      </ScrollView>
    </SafeAreaView>

这是我认为最愚蠢的简单方法:

<ScrollView style={{backgroundColor: '#000000'}}>
  [...]
  <View style={{position: "absolute", bottom: -600, left: 0, right: 0, backgroundColor: '#FFFFFF', height: 600}}/>
</ScrollView>

您可以根据自己的喜好调整 height/bottom 绝对值,具体取决于您认为用户可以滚动的距离。

我亲自将其实现到 <ScrollBottom color={"white"}/> 组件中,以便于在我所有的 ScrollViews 中使用