130 lines
2.9 KiB
JavaScript
130 lines
2.9 KiB
JavaScript
import { ScrollView, View, Animated, LayoutAnimation } from "react-native";
|
|
import React, { useState } from "react";
|
|
|
|
export const DynamicHeaderScrollView = (props) => {
|
|
const {
|
|
Max_Header_Height = 200,
|
|
Min_Header_Height = 80,
|
|
children,
|
|
scrollViewProps = {},
|
|
containerProps = {},
|
|
shortHeader = <></>,
|
|
longHeader = <></>,
|
|
topStickyContent,
|
|
styles,
|
|
} = props;
|
|
|
|
const Scroll_Distance = Max_Header_Height - Min_Header_Height;
|
|
|
|
const [headerVisible, setHeaderVisible] = useState(false);
|
|
const shotHeaderStyle = {
|
|
on: {
|
|
height: Min_Header_Height,
|
|
backgroundColor: "#0099CC",
|
|
margin: 0,
|
|
top: 0,
|
|
opacity: 1,
|
|
},
|
|
off: {
|
|
height: Max_Header_Height,
|
|
backgroundColor: "#0099CC",
|
|
margin: 0,
|
|
top: 0,
|
|
opacity: 0,
|
|
},
|
|
};
|
|
|
|
const longHeaderStyle = {
|
|
on: {
|
|
height: Max_Header_Height,
|
|
backgroundColor: "#0099CC",
|
|
margin: 0,
|
|
top: 0,
|
|
opacity: 1,
|
|
},
|
|
off: {
|
|
height: 0,
|
|
backgroundColor: "#0099CC",
|
|
margin: 0,
|
|
top: 0,
|
|
opacity: 0,
|
|
},
|
|
};
|
|
const StickyStyle = {
|
|
on: {
|
|
position: "absolute",
|
|
width: "100%",
|
|
flex: 1,
|
|
top: Max_Header_Height,
|
|
zIndex: 1,
|
|
},
|
|
off: {
|
|
position: "absolute",
|
|
width: "100%",
|
|
flex: 1,
|
|
top: Min_Header_Height,
|
|
zIndex: 1,
|
|
},
|
|
};
|
|
|
|
return (
|
|
<View {...containerProps}>
|
|
<View style={{ zIndex: 1 }}>
|
|
<Animated.View
|
|
style={[
|
|
styles.header,
|
|
headerVisible ? shotHeaderStyle.on : shotHeaderStyle.off,
|
|
]}
|
|
>
|
|
{shortHeader}
|
|
</Animated.View>
|
|
<Animated.View
|
|
style={[
|
|
styles.header,
|
|
headerVisible ? longHeaderStyle.off : longHeaderStyle.on,
|
|
]}
|
|
>
|
|
{longHeader}
|
|
</Animated.View>
|
|
<Animated.View style={headerVisible ? StickyStyle.off : StickyStyle.on}>
|
|
{topStickyContent}
|
|
</Animated.View>
|
|
</View>
|
|
<ScrollView
|
|
{...scrollViewProps}
|
|
style={{
|
|
backgroundColor: "white",
|
|
zIndex: 0,
|
|
}}
|
|
stickyHeaderIndices={[1]}
|
|
scrollEventThrottle={16}
|
|
onScroll={(event) => {
|
|
const scrollY = event.nativeEvent.contentOffset.y;
|
|
LayoutAnimation.configureNext({
|
|
duration: 100,
|
|
update: { type: "easeOut" },
|
|
});
|
|
setHeaderVisible(Scroll_Distance < scrollY);
|
|
}}
|
|
>
|
|
<View
|
|
style={{
|
|
height: Scroll_Distance,
|
|
flexDirection: "column",
|
|
}}
|
|
/>
|
|
{topStickyContent && (
|
|
<View
|
|
style={{
|
|
paddingTop: Min_Header_Height + 40,
|
|
flexDirection: "column",
|
|
}}
|
|
index={1}
|
|
/>
|
|
)}
|
|
{children}
|
|
</ScrollView>
|
|
</View>
|
|
);
|
|
};
|