我正在尝试为菜单徽标设置动画以使其在单击时旋转。当旋转向上旋转时,我可以成功获得旋转,但是向下旋转时它会直接变为0,而不是通过旋转动画。
这是我的组件:
import React from 'react';
import { TouchableOpacity, Animated } from 'react-native';
import PropTypes from 'prop-types';
import styles from './styles';
const TabIcon = ({
route,
renderIcon,
onPress,
focused,
menuToggled,
activeTintColor,
inactiveTintColor,
}) => {
const isMenuLogo = route.params && route.params.navigationDisabled;
const animation = new Animated.Value(0);
Animated.timing(animation, {
toValue: menuToggled ? 1 : 0,
duration: 200,
useNativeDriver: true,
}).start();
const rotateInterpolate = animation.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '180deg'],
});
const animatedStyles = { transform: [{ rotate: rotateInterpolate }] };
const logoStyles = [animatedStyles, styles.logoStyle];
return (
<TouchableOpacity
style={styles.tabStyle}
onPress={onPress}
activeOpacity={isMenuLogo && 1}
>
<Animated.View style={isMenuLogo ? logoStyles : null}>
{
renderIcon({
route,
focused,
tintColor: focused
? activeTintColor
: inactiveTintColor,
})
}
</Animated.View>
</TouchableOpacity>
);
};
TabIcon.propTypes = {
route: PropTypes.shape({
key: PropTypes.string,
}).isRequired,
renderIcon: PropTypes.func.isRequired,
onPress: PropTypes.func,
focused: PropTypes.bool,
menuToggled: PropTypes.bool,
activeTintColor: PropTypes.string.isRequired,
inactiveTintColor: PropTypes.string.isRequired,
};
TabIcon.defaultProps = {
onPress: () => {},
focused: false,
menuToggled: false,
};
export default TabIcon;
我首先检查它是否已切换,然后再实际旋转它。该组件在另一个显示自定义底部标签导航的父组件中被调用。
当它向下旋转时,我应该为其制作其他动画吗?还是我当前的动画中缺少配置?
任何帮助和建议将不胜感激。谢谢。
答案 0 :(得分:0)
我认为该问题与以下事实有关:当您将animation
的初始值设置为0
时,它的初始值始终设置为const animation = new Animated.Value(0);
,因此不能反映切换菜单时所做的更改。 / p>
您需要更改:
const animation = new Animated.Value(menuToggled ? 0 : 1);
到
menuToggled
尽管进行更改将导致其他问题。因为menuToggled
影响动画的开始和结束位置,所以图标现在将从结束位置旋转到正确的开始位置。这是不理想的。
不过,我们可以通过为if-statement
设置默认值null来解决此问题。然后将动画包装在menuToggled
不是null
时才运行的import React from 'react';
import { View, StyleSheet, Animated, TouchableOpacity } from 'react-native';
import { Ionicons } from '@expo/vector-icons';
const TabIcon = ({
onPress,
menuToggled
}) => {
const logoStyles = [styles.logoStyle];
if (menuToggled !== null) {
const animation = new Animated.Value(menuToggled ? 0 : 1);
Animated.timing(animation, {
toValue: menuToggled ? 1 : 0,
duration: 200,
useNativeDriver: true
}).start();
const rotateInterpolate = animation.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '180deg']
});
const animatedStyles = { transform: [{ rotate: rotateInterpolate }] };
logoStyles.push(animatedStyles);
}
return (
<TouchableOpacity
style={styles.tabStyle}
onPress={onPress}
>
<Animated.View style={logoStyles}>
<Ionicons name="md-checkmark-circle" size={32} color="green" />
</Animated.View>
</TouchableOpacity>
);
};
export default class App extends React.Component {
state = {
menuToggled: null
}
toggleMenu = () => {
this.setState(prevState => {
return { menuToggled: !prevState.menuToggled };
});
}
render () {
return (
<View style={styles.container}>
<TabIcon
onPress={this.toggleMenu}
menuToggled={this.state.menuToggled}
/>
</View>
);
}
}
中。
以下是基于您的初始代码的示例:
TabIcon
我删除了您的#include <stdio.h>
int main(void)
{
int j = -5;
float k = j / 2;
printf("%d\n", j % 2);
printf("%1.1f\n", k);
}
组件,因为那里有很多与动画无关的东西。您应该可以轻松地将我所做的工作整合到您自己的组件中。 https://snack.expo.io/@andypandy/rotating-icon
答案 1 :(得分:0)
我已经在上面尝试过安德鲁的解决方案并且可以使用,但是我选择了将其转换为类组件。它的工作方式相同。请参阅下面的组件。
import React, { PureComponent } from 'react';
import { TouchableOpacity, Animated } from 'react-native';
import PropTypes from 'prop-types';
import styles from './styles';
class TabIcon extends PureComponent {
constructor(props) {
super(props);
this.state = {
animation: new Animated.Value(0),
};
}
render() {
const { animation } = this.state;
const {
route,
renderIcon,
onPress,
focused,
menuToggled,
activeTintColor,
inactiveTintColor,
} = this.props;
const isMenuLogo = route.params && route.params.navigationDisabled;
Animated.timing(animation, {
toValue: menuToggled ? 1 : 0,
duration: 200,
useNativeDriver: true,
}).start();
const rotateInterpolate = animation.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '180deg'],
});
const animatedStyles = { transform: [{ rotate: rotateInterpolate }] };
const logoStyles = [animatedStyles, styles.logoStyle];
return (
<TouchableOpacity
style={styles.tabStyle}
onPress={onPress}
activeOpacity={isMenuLogo && 1}
>
<Animated.View style={isMenuLogo ? logoStyles : null}>
{
renderIcon({
route,
focused,
tintColor: focused
? activeTintColor
: inactiveTintColor,
})
}
</Animated.View>
</TouchableOpacity>
);
}
}
TabIcon.propTypes = {
route: PropTypes.shape({
key: PropTypes.string,
}).isRequired,
renderIcon: PropTypes.func.isRequired,
onPress: PropTypes.func,
focused: PropTypes.bool,
menuToggled: PropTypes.bool,
activeTintColor: PropTypes.string.isRequired,
inactiveTintColor: PropTypes.string.isRequired,
};
TabIcon.defaultProps = {
onPress: () => {},
focused: false,
menuToggled: false,
};
export default TabIcon;