Правильно использовать Animated API в native - PullRequest
0 голосов
/ 11 декабря 2018

Я довольно новичок в Animated API в реагировать на нативный.Я прошел много уроков по использованию API анимации, и кажется, что в каждом из них элементы позиционируются как абсолютные, нужно ли позиционировать элемент как абсолютные?

Также я сделал фрагмент анимации, но этовыглядит сбой, я думаю, что представление после textinput donot имеет абсолютную позицию, которая может быть причиной проблемы.Можно ли сделать анимацию, которую я пытаюсь сохранить, сохраняя абсолютную позицию ввода текста, но другие элементы располагаются с помощью flexbox?

Вот код

handleFocus = () => {
console.log('starting animation');
this.setState({
  isFocused: true
});
Animated.timing(this.isFromViewFocused, {
  toValue: 1,
  duration: 300
}).start();
}

handleBlur = () => {
console.log('Blurring');
this.setState({
  isFocused: false
});
Animated.timing(this.isFromViewFocused, {
  toValue: 0,
  duration: 300
}).start();
}

render() {
const labelStyle = {
  position: this.state.isFocused === true ? 'absolute' : 'relative',
  alignItems: 'center',
  width: this.isFromViewFocused.interpolate({
    inputRange: [0, 1],
    outputRange: [DEVICE_WIDTH * 0.45, DEVICE_WIDTH]
  }),
  left: this.isFromViewFocused.interpolate({
    inputRange: [0, 1],
    outputRange: [DEVICE_WIDTH * 0.03, 0]
  }),
  marginBottom: this.isFromViewFocused.interpolate({
    inputRange: [0, 1],
    outputRange: [0, 80]
  }),
  top: this.isFromViewFocused.interpolate({
    inputRange: [0, 1],
    outputRange: [10, 0]
  }),
  borderWidth: this.isFromViewFocused.interpolate({
    inputRange: [0, 1],
    outputRange: [0, 5]
  }),
  borderColor: 'black',
  paddingTop: this.state.isFocused === true ? 20 : 0
 };
return (
  <View style={styles.container}>
    <ScrollView style={{ flex: 1 }} keyboardDismissMode='on-drag'>

      <Animated.View
      style={labelStyle}
      >

        <TextInput
        onFocus={this.handleFocus}
        onBlur={this.handleBlur}
        style={{
          borderColor: 'black',
          borderWidth: 1,
          width: '90%'
        }}
        >
          <Text>Hey Text</Text>
        </TextInput>
      </Animated.View>

      <Animated.View
      style={[styles.LocationContainer,
        { marginTop: this.isFromViewFocused.interpolate({
          inputRange: [0, 1],
          outputRange: [20, 80]
        })
      }
    ]}>

1 Ответ

0 голосов
/ 11 декабря 2018

Использование позиционирования absolute в сочетании с left, top, bottom, right плохо для исполнения.Вот почему ваши анимации выглядят «глючно».

Было бы лучше использовать преобразования, чтобы ваш компонент оставался relative, а собственные оптимизации можно было сделать (так же, как преобразования CSS3).

Кроме того,при использовании неоптимизируемых свойств (например, тех, которые вы используете) вы не можете установить useNativeDriver в значение true.Что делает производительность еще хуже.

Чтобы добавить к этому, вы не можете (или не должны) интерполировать на основе логического значения.AnimatedJS предоставляет вам класс Animated.Value, цель которого - упростить интерполяцию.

Вот более простой пример для Animated:

export class MyAnimatedComponent extends React.Component {

  state = {
    animatedValue: new Animated.Value(0);
  }

  focus = () => {
    const { animatedValue } = this.state;
    Animated.timing(animatedValue, {
      duration: 280,
      toValue: 1,

      // This will make your animation glitch-free/performant.
      useNativeDriver: true,
    }).start();
  }

  blur = () => {
    Animated.timing(animatedValue, {
      duration: 140,
      toValue: 0,

      // This will make your animation glitch-free/performant.
      useNativeDriver: true,
    }).start();
  }

  render () {
    const { animatedValue } = this.state;
    const animatedStyles = {
      transform: [
        {
          // Move the div by 120px to the left when value === 1
          translateX: animatedValue.interpolate(
            inputRange: [0, 1],
            outputRange: [0, -120],

            // Tells Animated to never go outside of the outputRange
            extrapolate: 'clamp',
          ) 
        },
        {
          translateY: animatedValue.interpolate(
            inputRange: [0, 1],
            outputRange: [0, -50],
            extrapolate: 'clamp',
          )
        }
      ]
    }

    return (
      <View style={styles.wrapper}>
        <Animated.View style={animatedStyles} onFocus={onFocus} onBlur={onBlur}>
          I'm some content into an Animated div.
        </Animated.View>
      </View>
    )
  }
}
...