React Native
[React-Native] Animated View
sayhee
2023. 1. 26. 19:04
728x90
Animated.View를 사용하여 구현해보았습니당
✅ Animated 기준값을 전역변수로 지정
constructor(props) {
super(props);
this.AnimatedHeaderValue = new Animated.Value(0); // Animated 기준값(0,0)
this.state = {
goodsContent: [],
indicator : false,
};
}
✅ render 부분에 Animated.View 사용
render() {
const Header_Maximum_Height = 120;
const Header_Minimum_Height = 60;
const renderHeader = this.AnimatedHeaderValue.interpolate(
{
inputRange: [0, Header_Maximum_Height],
outputRange: [0, -Header_Maximum_Height],
});
const renderSearchBar = this.AnimatedHeaderValue.interpolate(
{
inputRange: [0, Header_Maximum_Height],
outputRange: [Header_Maximum_Height, 0],
extrapolate: 'clamp'
});
return (
<>
<View style={{ flex: 1 }}>
<FlatList
style={styles.goodsContent}
data={this.state.goodsContent}
renderItem={({ item , index }) => <ListItem index={index} item={item} id={item.id} navigation={this.props.navigation} />}
refreshing={this.state.refreshing} //새로고침
onRefresh={this.handleRefresh}
scrollEventThrottle={16}
contentContainerStyle={{ paddingTop: Header_Maximum_Height + Header_Minimum_Height+30 }}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: this.AnimatedHeaderValue } } }],
{ useNativeDriver: false })}
/>
<Animated.View style={[styles.homeTop, { transform: [{ translateY: renderHeader }] }]}>
<ImageBackground source={require('../../../images/background/main-background/main-background.png')} style={{ width: "100%", height: "100%" }}>
<View style={styles.title}>
<View style={styles.titleRow}>
<Text style={[styles.titleText, styles.titleBoldText]}>
손 쉽게 검색
</Text>
...
</View>
</ImageBackground>
</Animated.View>
<Animated.View style={[styles.searchBarStyle, { height: Header_Minimum_Height, transform: [{ translateY: renderSearchBar }] }]}>
<ImageBackground source={require('../../../images/background/main-background/main-background.png')} style={{ width: "100%", height: "100%", flexDirection: 'row' }}>
<TextInput
onChange={(value) => this.search(value.nativeEvent.text)}
placeholder="품명을 입력해주세요"
placeholderTextColor="light grey"
style={styles.input}
value={this.state.number}
/>
{/* 카메라로 검색 */}
<TouchableOpacity
style={styles.cameraSearchButton}
onPress={this.goCameraButtonClicked}>
<Image
source={require('../../../images/icon/camera-icon/camera-icon.png')}
/>
</TouchableOpacity>
</ImageBackground>
...
</Animated.View>
</View>
</>
);
}
Header_Maximum_Height 는 검색 부분 위의 Header 부분의 높이
Header_Minimum_Height 는 검색 부분의 높이
renderSearchBar에 exrtapolate를 clamp로 주었습니다.
📍 clamp는 interpolate에서 Animated value가 inputRage의 범위를 벗어났을 때
outputRage의 최대(또는 최소) 값을 반환합니다.
즉, inputRange안에서의 값만 변화가 있고 Animated Value가 inputRange를 벗어나면 변화가 없습니다.
따라서 renderSearchBar만 남을 수 있게 되는 것이죠!
💡 extrapolate를 주지 않았을 경우