【发布时间】:2016-11-01 18:13:45
【问题描述】:
我有一个ScrollView,它的顶部带有一种背景颜色,底部带有另一种不同的颜色。
当用户滚动过内容并且视图反弹(弹性过度延伸)时,我怎样才能使背景与顶部或底部一致,具体取决于滚动方向?
【问题讨论】:
标签: javascript react-native react-native-ios
我有一个ScrollView,它的顶部带有一种背景颜色,底部带有另一种不同的颜色。
当用户滚动过内容并且视图反弹(弹性过度延伸)时,我怎样才能使背景与顶部或底部一致,具体取决于滚动方向?
【问题讨论】:
标签: javascript react-native react-native-ios
我不会使用滚动视图的contentInset 和contentOffset,因为如果您的内容发生变化,它可能会改变滚动视图的位置。
您可以通过在 ScrollView 的最顶部添加一个 View 来做一些非常简单的事情:
// const spacerHeight = 1000;
<ScrollView>
{Platform.OS === 'ios' && (
<View
style={{
backgroundColor: 'red',
height: spacerHeight,
position: 'absolute',
top: -spacerHeight,
left: 0,
right: 0,
}}
/>
)}
</ScrollView>
【讨论】:
在 iOS 上,您可以在 ScrollView 之上渲染一个间隔 View,并使用 contentInset 将其渲染为“离屏”,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>
);
}
因为contentInset 和contentOffset 是仅限iOS,所以此示例适用于在Android 上正常降级。
【讨论】:
接受的解决方案对我来说效果不佳,因为我需要将 flexGrow: 1 放在 contentContainerStyle 上。使用 insets/offsets 并没有使内容按照我想要的方式增长,否则效果还不错。
我有另一个解决方案建议:在透明的 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 上的背景颜色很好)
【讨论】:
对我来说,最简单的解决方案是基于 Sebastien Lorber 答案进行修改,不包括包装,只需在 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>
您可以根据自己的喜好调整高度/底部的绝对值,具体取决于您认为用户可以滚动多远。
我亲自将它实现到 <ScrollBottom color={"white"}/> 组件中,以便在我所有的 ScrollViews 中使用
【讨论】: