来回动画来回旋转徽标点击并做出反应

时间:2019-02-24 06:28:31

标签: reactjs react-native animation react-navigation

我正在尝试为菜单徽标设置动画以使其在单击时旋转。当旋转向上旋转时,我可以成功获得旋转,但是向下旋转时它会直接变为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;

我首先检查它是否已切换,然后再实际旋转它。该组件在另一个显示自定义底部标签导航的父组件中被调用。

当它向下旋转时,我应该为其制作其他动画吗?还是我当前的动画中缺少配置?

任何帮助和建议将不胜感激。谢谢。

2 个答案:

答案 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;