EDIT: I hate googling for answers and finding some question that never got solved from 10 years ago so I am answering my own question for those that might want to know. In my case, I simply disabled the bounces
prop for the scrollview. Since FlatList extends React's ScrollView, setting bounces
to false
in the animated FlatList component that I created stopped it from bouncing and solved my problem. Have a nice day.
hope you're having a great day. I am trying to animate my header dynamically but for some reason whenever I scroll beyond the beginning or the end of the scrollview, the bounce effect messes with the Animation.(as shown in the gif below)
GIF
Same GIF but higher resolution
As you can see, when I scroll to the top and enable the bounce animation, the header thinks that i am scrolling down as the bounce returns the first element in the list back to the top. How do I fix this? I saw on the web somewhere that adding an interpolator to the animated value would help, though I don't really understand. Below is my code. Thank You
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList)
const tempArray = [
...(an array of my data)
]
export default class TempScreen extends React.Component {
static navigationOptions = {
header: null
}
constructor(props) {
super(props)
this.state = {
animatedHeaderValue: new Animated.Value(0),
}
}
render() {
const animatedHeaderHeight = Animated.diffClamp(this.state.animatedHeaderValue, 0, 60)
.interpolate({
inputRange: [0, 70],
outputRange: [70, 0],
})
return ( <
View >
<
Animated.View style = {
{
backgroundColor: 'white',
borderBottomColor: '#DEDEDE',
borderBottomWidth: 1,
padding: 15,
width: Dimensions.get('window').width,
height: animatedHeaderHeight,
}
} >
<
/Animated.View> <
AnimatedFlatList scrollEventThrottle = {
16
}
onScroll = {
Animated.event(
[{
nativeEvent: {
contentOffset: {
y: this.state.animatedHeaderValue
}
}
}]
)
}
data = {
tempArray
}
renderItem = {
({
item
}) =>
<
View style = {
{
flex: 1
}
} >
<
Text style = {
{
fontWeight: 'bold',
fontSize: 30
}
} > {
item.name
} < /Text> <
Text > {
item.year
} < /Text> <
/View>
}
/>
<
/View>
)
}
}
If you want to solve the "bounce" problem only, the problem is that iOS gives to diffClamp negative scrollY values. You need to filter these and ensure scrollY remains >= 0 to avoid diffClamp being affected by overscroll.
const clampedScrollY = scrollY.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolateLeft: 'clamp',
});
Another nice trick is to use a "cliff" technique, so that the header only disappear after a minimum scrollY position.
Here is code from my app:
const minScroll = 100;
const clampedScrollY = scrollY.interpolate({
inputRange: [minScroll, minScroll + 1],
outputRange: [0, 1],
extrapolateLeft: 'clamp',
});
const minusScrollY = Animated.multiply(clampedScrollY, -1);
const translateY = Animated.diffClamp(
minusScrollY,
-AnimatedHeaderHeight,
0,
);
const opacity = translateY.interpolate({
inputRange: [-AnimatedHeaderHeight, 0],
outputRange: [0.4, 1],
extrapolate: 'clamp',
});
clampedScrollY
will be:
You get the idea. So diffClamp
will only be > 0 if scrollY > 100, and increment 1 by 1 after that threshold.
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