Reputation: 2989
I'm really new to react-native. I'm trying to create a button with a progress indicator and want to execute some code on the progress completion. Somehow I have achieved the desired behaviour using the following code,
React Component
class ProgressButton extends Component {
constructor() {
super();
this.state = {
progress: 100,
};
this.progressTimer = null;
}
componentDidMount() {
this.progressTimer = setInterval(() => {
if(this.state.progress === 0) {
clearInterval(this.progressTimer);
// Run code on completion
}
this.setState({progress: this.state.progress - 1})
}, 100)
}
render() {
return (
<button style={{backgroundPosition: this.state.progress + '%'}}>
Hello
</button>
);
}
}
CSS
button {
font-size: 16px;
width: 70px;
height: 30px;
border-radius: 4px;
border: none;
background-size: 200% 100%;
background-image: linear-gradient(to right, black 50%, grey 50%);
color: white;
background-position: 100% 0;
}
But I'm not satisfied with this solution because,
setInterval()
is a good idea.I have thought about doing the same with a CSS @keyframes
animation and setTimeout()
to execute the code on completion. But I'm not sure about it either because it may not be in sync.
Is there a better way to do this?
Upvotes: 2
Views: 426
Reputation: 7985
Friend I shortened the way for you with animations
import { Animated} from 'react-native';
//in constructor
this.state = {
progress: new Animated.Value(0);
};
//in componentDidMount
Animated.timing(this.state.progress, {
toValue: 100,//That you are interested
duration: 500
}).start()
//in render
const animator = this.state.progress.interpolate({
inputRange: [0, 100],
outputRange: ['1%', '100%'],
});
//use animator in style
<Animated.View style={{height:animator}}/>
for you
import React, {Component} from 'react';
import {View, Text, Animated, Easing, TouchableHighlight} from 'react-native';
class App extends Component {
constructor() {
super();
this.ani = new Animated.Value(0);
}
componentDidMount(): void {
Animated.timing(this.ani, {
toValue: 2,
duration: 3000,
easing: Easing.linear,
}).start(() => {
// Do something after animation (optional).
});
}
render() {
const animator = this.ani.interpolate({
inputRange: [0, 1],
outputRange: ['5%', '100%'],
});
return (
<Animated.View
style={{
flex: 1,
justifyContent: 'center',
}}>
<Animated.View
style={{
height: 60,
backgroundColor: 'blue',
width: animator,
}}>
<TouchableHighlight>
<Text>press me</Text>
</TouchableHighlight>
</Animated.View>
</Animated.View>
);
}
}
export default App;
Upvotes: 1