在我的React Native应用程序的标题中,我有一个条件图标和一个Searchbar。
static navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state;
return {
headerTitle: (
<View
style={{
flex: 1,
backgroundColor: Platform.OS === 'ios' ? '#e54b4d' : '',
alignItems: 'center',
flexDirection: 'row',
paddingHorizontal: 10,
height: StatusBar.currentHeight,
}}>
{params.isIconTriggered && <Icon name="chevron-left" size={28} />}
<SearchBar
round
platform={'default'}
placeholder="Search"
containerStyle={{
flex: 1,
backgroundColor: 'transparent',
}}
/>
</View>
),
headerStyle: {
backgroundColor: '#e54b4d',
},
};
};
通常,搜索栏将采用标题的全部宽度,这正是我想要的。如果条件isIconTriggered
为真,则图标将出现在搜索栏的前面,并且搜索栏的宽度将缩小到足以使其旁边可见的程度。
但是,发生这种情况时没有过渡或动画,并且感觉也不好。我想在搜索栏中添加动画,以便在触发条件并显示图标时宽度逐渐平滑地缩小。
那有可能实现吗,我该如何实现呢?
答案 0 :(得分:6)
尝试学习react native的动画API。
这是我通过按钮触发器完成的操作。
import React, {Component} from 'react';
import {StyleSheet, View, TextInput , Button, SafeAreaView, Animated} from 'react-native';
import FA from 'react-native-vector-icons/FontAwesome5'
const AnimatedIcon = Animated.createAnimatedComponent(FA)
// make your icon animatable using createAnimatedComponent method
export default class Application extends Component {
animVal = new Animated.Value(0);
// initialize animated value to use for animation, whereas initial value is zero
interpolateIcon = this.animVal.interpolate({inputRange:[0,1], outputRange:[0,1]})
interpolateBar = this.animVal.interpolate({inputRange:[0,1],outputRange:['100%','90%']})
// initialize interpolation to control the output value that will be passed on styles
// since we will animate both search bar and icon. we need to initialize both
// on icon we will animate the scale whereas outputRange starts at 0 end in 1
// on search bar we will animate width. whereas outputRange starts at 100% end in 90%
animatedTransition = Animated.spring(this.animVal,{toValue:1})
// we use spring to make the animation bouncy . and it will animate to Value 1
clickAnimate = () => {
this.animatedTransition.start()
}
// button trigger for animation
//Components that will use on Animation must be Animated eg. Animted.View
render() {
return (
<SafeAreaView>
<View style={styles.container}>
<View style={styles.search}>
{/* our icon */}
<Animated.View style={{width: this.interpolateBar}}>
<TextInput placeholder='search here' style={styles.input}/>
</Animated.View>
<AnimatedIcon name='search' size={28} style={{paddingLeft: 10,paddingRight:10, transform:[{scale: this.interpolateIcon}]}}/>
</View>
<Button title='animate icon' onPress={this.clickAnimate}/>
</View>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor:'#F79D42',
// flex: 1,
height:'100%',
paddingTop:20,
flexDirection: 'column',
// justifyContent: 'center',
alignItems:'center'
},
input:{
width: '100%',
height:40,
backgroundColor:'gray',
textAlign:'center'
},
search:{
flexDirection:'row-reverse',
width:'90%',
height:40,
alignItems:'center'
}
});
使用react-native-elements SearchBar组件的解决方案。 将SearchBar组件包装在Animated.View中。 明确为搜索栏设置动画
赞!
<Animated.View style={{width: this.interpolateBar}}>
<SearchBar
placeholder="Type Here..."
containerStyle={{width: '100%'}}
/>
</Animated.View>
答案 1 :(得分:1)
答案 2 :(得分:0)
React-Native-Animatable非常酷! 试试这个:
import * as Animatable from 'react-native-animatable';
Animatable.initializeRegistryWithDefinitions({
const myAnimation = {
from: {
width: 200
},
to: {
width: 100
}
}
})
在视图中用作动画值或在函数调用中用作引用。
在视图内:
<Animatable.View useNativeDriver animation={myAnimation}/>
<Animatable.View useNativeDriver ref={ref=>(this.testAnimation = ref)}/>
方法:
testMethod = () => {
this.testAnimation.myAnimation();
}