反应相互影响的本机动画组件

时间:2020-05-16 17:39:36

标签: react-native react-animated

上下文:

我有一个名为AnimatedSlider的组件,并且在App.js中被使用了两次。

AnimatedSlider使用React.Animated设置其中View的宽度的动画。这是代码。

AnimatedSlider.js

import React, { useRef } from 'react';
import {
  Text,
  View,
  StyleSheet,
  TouchableWithoutFeedback,
  Animated,
  Easing,
} from 'react-native';

const { Value } = Animated;

const MENU_ITEM_WIDTH = 50;
const MENU_ITEM_FINAL_WIDTH = 200;
const sliderWidthAnimatedValue = new Value(MENU_ITEM_WIDTH);

export default function AnimatedSlider() {
  const sliderState = useRef(-1);

  const animateExpantion = () => {
    Animated.timing(sliderWidthAnimatedValue, {
      toValue: MENU_ITEM_FINAL_WIDTH,
      duration: 250,
      easing: Easing.linear,
      useNativeDriver: false,
    }).start();
  };

  const animateCollapse = () => {
    Animated.timing(sliderWidthAnimatedValue, {
      toValue: MENU_ITEM_WIDTH,
      duration: 250,
      easing: Easing.linear,
      useNativeDriver: false,
    }).start();
  };

  const animateSlider = () => {
    if (sliderState.current === -1) {
      animateExpantion();
      sliderState.current = 1;
    } else {
      animateCollapse();
      sliderState.current = -1;
    }
  };

  return (
    <View style={styles.container}>
      <Text>Label</Text>
      <TouchableWithoutFeedback onPress={animateSlider}>
        <Animated.View
          style={[styles.slidingMenu, { width: sliderWidthAnimatedValue }]}
        />
      </TouchableWithoutFeedback>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    width: '100%',
    height: 50,
    display: 'flex',
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'space-between',
    paddingLeft: 24,
    marginBottom: 10,
    backgroundColor: 'grey',
  },
  slidingMenu: {
    height: '100%',
    width: MENU_ITEM_WIDTH,
    backgroundColor: 'pink',
  },
});

App.js

import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import Constants from 'expo-constants';

import AnimatedSlider from './components/AnimatedSlider';

export default function App() {
  return (
    <View style={styles.container}>
        <AnimatedSlider menuColor='pink'/>
        <AnimatedSlider menuColor='pink'/>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
});

问题:单击一个组件,似乎也可以使另一个动画。

您可以查看小吃here

1 个答案:

答案 0 :(得分:0)

问题出在下一行的位置。

const sliderWidthAnimatedValue = new Value(MENU_ITEM_WIDTH);

将其移动到组件中可以解决此问题。原因是Value的实例,因此slideWidthAnimatedValue组件的实例之间共享AniatedSlider