i am currently trying to hide my search bar when scrolling.
The components i have on screen are a search bar at the top followed by a horizontal scroll view with tabs, then my flatlist.
with the current implementation, when i load the screen, the search bar is covering the tabs and when i scroll down the search bar hides and the tabs appear.
What i am trying to do is, when i load the screen the search bar, tabs and flatlist should all be visible then when i start scrolling the search bar hides and the tabs and flatlist fill the available space at the top.
Also, another problem i am encountering is when i keep scrolling up the search bar keeps moving up until it disappears.
here is my code:
const scrollY = new Animated.Value(0)
const diffClamp=Animated.diffClamp(scrollY,0,100)
const translateY = diffClamp.interpolate({
inputRange:[0,100],
outputRange:[0,-100]
})
return(
<Animated.View style={{transform:
[{translateY:translateY}],elevation:4,zIndex:100}}>
<SearchBar
containerStyle={{height:40,marginBottom:20,position:"absolute",
left:0,right:0,top:0}}
inputContainerStyle={{height:40}}
/>
</Animated.View>
<View style={{paddingHorizontal:6}}>
<ScrollView
horizontal
style={{
marginBottom:10,
height:30,
}}
showsHorizontalScrollIndicator={false}
>
{categories.map(e=>(
<TouchableOpacity
style={[
{paddingHorizontal:10,paddingBottom:0},
label===e.label &&
{
borderRadius:2,
marginBottom:-20,
}
]}
onPress={()=>}
>
<AppText>{e.label}</AppText>
</TouchableOpacity>
))}
</ScrollView>
</View>
<FlatList
data={posts} // to have all the data
keyExtractor={(post) => post.id.toString()}
renderItem={({ item,index }) => (
<Card
title={item.title}
subTitle={item.subTitle}
/>
)}
onScroll={(e)=>{
scrollY.setValue(e.nativeEvent.contentOffset.y)
}}
/>
)
with position:"absolute", the search bar is on top on the tabs so instead of position:"absolute" i tried "relative", when i scroll down the search bar hides but there is blank space above the tabs.
I am also using the react native elements search bar component.
would appreciate any help possible, thank you in advance.
UPDATE
After following J.Doe solution, which is the correct solution to solving the translation problem, i now faced a new problem correlating to this.
Since i can toggle between the different tabs in my scrollView, each tab has its corresponding Flatlist data. If the FlatList has more than 3 data items the functionality works correct, but if it has 1 or 2 data items then the translation functionality stops working.
if i am on tab 1 (with many data items) and scroll down (ie. search bar is translated) then tap on tab 2 that only contains 1 data item, i am not able to scroll the screen to see the search bar.
Here is my code:
const categories = [
{
label: "Sports",
id: 1,
},
{
label: "News",
id: 2,
},
{
label: "Food",
id: 3,
},
]
const[label,setLabel]=useState(categories[0]?.label)
const [currentCategoryId, setCurrentCategoryId] = useState(1)
const setLabelFilter=label=>{
setLabel(label)
}
const toggleBrands = (categoryId) => {
setCurrentCategoryId(categoryId)
};
Here is my scrollView:
<ScrollView
horizontal
style={{
flexDirection:"row",
alignContent:"center",
marginTop: 20,// space between tabs and search bar
height:30,
}}
showsHorizontalScrollIndicator={false}
>
{categories.map((e)=>(
<TouchableOpacity
key={e.id}
onPress={()=>{
toggleBrands(e.id),
setLabelFilter(e.label)
}}
selected={e.id === currentCategoryId}
>
<AppText style={[{fontWeight:"500"},label===e.label && {fontWeight:"700"}]}>{e.label}</AppText>
</TouchableOpacity>
))}
</ScrollView>
import React from 'react';
import {
View,
Animated,
Text,
StyleSheet,
ScrollView,
RefreshControl,
} from 'react-native';
const data = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];
const App = () => {
const scrollY = React.useRef(new Animated.Value(0)).current;
const diffClamp = Animated.diffClamp(scrollY, 0, 100);
const translateY = diffClamp.interpolate({
inputRange: [0, 100],
outputRange: [0, -60],
extrapolate: 'clamp',
});
const marginTop = diffClamp.interpolate({
inputRange: [0, 100],
outputRange: [0, -60],
extrapolate: 'clamp',
});
const paddingTop = diffClamp.interpolate({
inputRange: [0, 100],
outputRange: [10, 110],
extrapolate: 'clamp',
});
const opacity = diffClamp.interpolate({
inputRange: [0, 100],
outputRange: [1, 0],
extrapolate: 'clamp',
});
const renderItem = ({item}) => {
return (
<View style={styles.card}>
<Text>{`Card ${item}`}</Text>
</View>
);
};
return (
<View style={{flex: 1, backgroundColor: 'red'}}>
<Animated.View
style={{
zIndex: 100,
paddingBottom: 10,
transform: [{translateY}],
}}>
<Animated.View style={[styles.searchBar, {opacity}]}>
<Text>Search Bar</Text>
</Animated.View>
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
{data.map((num) => {
return (
<View key={num} style={styles.tab}>
<Text>Tab</Text>
</View>
);
})}
</ScrollView>
</Animated.View>
<Animated.FlatList
style={{marginTop, paddingTop}}
// contentContainerStyle={{paddingTop: 150}}
refreshControl={
<RefreshControl
tintColor="#fff"
onRefresh={() => {
console.warn('Refreshing');
}}
refreshing={false}
/>
}
bounces={true}
data={data}
keyExtractor={(item) => item}
scrollEventThrottle={16}
renderItem={renderItem}
onScroll={(e) => {
if (e.nativeEvent.contentOffset.y > 0)
scrollY.setValue(e.nativeEvent.contentOffset.y);
}}
/>
</View>
);
};
const styles = StyleSheet.create({
searchBar: {
marginHorizontal: '5%',
width: '90%',
marginTop: 40,
height: 40,
borderRadius: 10,
borderColor: 'lightgray',
borderWidth: 1,
backgroundColor: '#f4f4f4',
justifyContent: 'center',
alignItems: 'center',
},
tab: {
justifyContent: 'center',
alignItems: 'center',
marginTop: 20,
marginHorizontal: 20,
width: 70,
height: 30,
borderRadius: 10,
backgroundColor: 'pink',
},
card: {
width: '90%',
marginLeft: '5%',
height: 100,
borderRadius: 10,
backgroundColor: 'yellow',
marginBottom: 20,
justifyContent: 'center',
alignItems: 'center',
},
});
export default App;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With