Reputation: 85
I want to animate the backgroundColor of a ScrollView, but always get a warning - and a non-animating ScrollView. Am I hitting a bug? Or is it simply not supported on a ScrollView? (It does work on a regular View.) I'm testing using Expo on an iOS iPhone.
Relevant code snippets:
<Animated.ScrollView
contentContainerStyle={[
styles.container,
this.getCurrentColorOfBackground()
]}>
<Text onPress={this.onPress} style={styles.question}>
{this.state.question}
</Text>
</Animated.ScrollView>
the getCurrentColorOfBackground() method:
getCurrentColorOfBackground = () => ({
backgroundColor: this.backgroundColor.interpolate({
inputRange: [0, 100],
outputRange: ["#00aaFF", "#808080"]
})
});
the animation itself:
this.backgroundColor = new Animated.Value(0);
Animated.timing(this.backgroundColor, {
toValue: 100,
duration: 1000 * 60
}).start();
The warning message:
20:17:58: Warning: Failed prop type: Invalid prop
backgroundColor
supplied toScrollView
: [object Object] Valid color formats are - '#f0f' (#rgb) - '#f0fc' (#rgba) - '#ff00ff' (#rrggbb) - '#ff00ff00' (#rrggbbaa) - 'rgb(255, 255, 255)' - 'rgba(255, 255, 255, 1.0)' - 'hsl(360, 100%, 100%)' - 'hsla(360, 100%, 100%, 1.0)' - 'transparent' - 'red' - 0xff00ff00 (0xrrggbbaa)Bad object: { "flexGrow": 1, "alignItems": "center",
"justifyContent": "center", "backgroundColor": "rgba(0, 170, 255, 1)" } in ScrollView (at createAnimatedComponent.js:154)
In case you want to try it out yourself, the full component (and repo) is here: https://github.com/wim82/chapter-interview/blob/master/QuestionRotator.js
Upvotes: 0
Views: 8728
Reputation: 4200
You can't animate any properties of contentContainerStyle
of a scrollview because the underlying component, ScrollContentContainerViewClass
, is hardcoded by react-native and can't be changed. See the source code here:
https://github.com/facebook/react-native/blob/bbb6a0754ce4173e24d3c0b46a5350ff2a8690d3/Libraries/Components/ScrollView/ScrollView.js#L790-L802
You would need to open an issue and then submit a pull request adding a property to scrollView that would allow you to set ScrollContentContainerViewClass
.
Upvotes: 0
Reputation: 6677
Apply the backgroundColor inside the style property instead of contentContainerStyle of scrollView.
The Animated.Value(0) should be stored in the state, not as a class object (from the official docs and best practice).
I have modified your above code to make it work,
import React, { Component } from 'react';
import { Text, StyleSheet, Animated } from 'react-native';
export default class App extends Component {
constructor (props) {
super(props);
// Intialize to default value
this.state = {
backgroundColor: new Animated.Value(0)
};
}
onPress = () => {
// onPress, initialize to default value using setState and start animation
// after the state has been updated
this.setState({ backgroundColor: new Animated.Value(0) }, () => {
Animated.timing(this.state.backgroundColor, {
toValue: 100,
duration: 5000
}).start();
});
}
render() {
return (
<Animated.ScrollView
style={[
styles.container,
// Interpolation mapping from numbers to strings (colors)
{
backgroundColor: this.state.backgroundColor.interpolate({
inputRange: [0, 100],
outputRange: ["#00aaFF", "#808080"]
})
}
]}
>
<Text
// onPress to start Animation
onPress={() => this.onPress() }
style={styles.paragraph}
>
Change code in the editor and watch it change on your phone!
Save to get a shareable url.
</Text>
</Animated.ScrollView>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
paragraph: {
margin: 24,
fontSize: 18,
fontWeight: 'bold',
textAlign: 'center',
color: '#34495e',
},
});
Working snack example: https://snack.expo.io/BymzMdtRG
Hope this helps.
Upvotes: 3