原生动画模块不支持样式属性“宽度”:需要建议重写我的代码

Yos*_*ssi 1 android-animation react-native react-native-animatable

我继承了以下组件,它与以前版本的 react-native 配合得很好,在其他组件显示的按钮上显示不透明的滚动进度条。

最近,当我升级到 react-native 0.62.2 时出现错误,要求添加 useNativeDriver. 添加它并将其设置为“是”时,我收到一条错误消息,指出“ style property 'width' is not supported by native animated module”。

当设置useNativeDriver为 false 时,我没有收到错误,但动画不起作用(至少在 android 上不是。没有在 iOS 上测试)。

关于如何修改代码以使其适用于最新版本的 react-native 的任何建议?

import React, { Component } from 'react';
import { Animated, Easing } from 'react-native';
import { connect } from 'react-redux';

class ProgressBar_Module extends Component {
  constructor(props) {
    super(props);

    this.state = {
      progress: 0
    }
    this.d_isMounted = false;
    this.d_initialTime = 0;
    this.d_animation_width = new Animated.Value(1);
    this.d_animation_progressTime = 3000;
  }

  componentDidMount() {
    this.d_initialTime = Date.now();
    this.d_isMounted = true;
    this.progressCount();
  }

  componentDidUpdate(prevProps) {
    if(prevProps.timerStart < this.props.timerStart) {
      this.setState({
        animation_width: new Animated.Value(1),
        animation_progressTime: 3000
      });
      this.progressCount(true)
    }
  }

  componentWillUnmount() {
    this.d_isMounted = false;
  }

  progressCount = (reset) => {
    if( reset ) {
      this.d_animation_width = new Animated.Value(1);
      this.d_animation_progressTime = 3000;
    }
    Animated.timing(this.d_animation_width, {
      toValue: 175,
      duration: this.d_animation_progressTime,
      easing: Easing.linear
    }).start(() => {
      if(this.props.timer && this.d_animation_width.__getValue() === 175) {
        this.props.onPress();
      }
    })
  }

  render() {

    return (
      <Animated.View
        style={[
          {
            position: 'absolute',
            left: 0,
            height: '150%',
            width: 0,
            zIndex: 1,
            backgroundColor: 'black',
          },
          { width: this.props.timer !== false ?
              this.d_animation_width : 175 }
        ]}
        onPress={this.props.onPress}
      >
      </Animated.View>
    )
  }
}

const mapStateToProps = state => {
  return {
    timer: state.get('ui').get('timer').get('timer'),
    reset: state.get('ui').get('resetTimer').get('resetTimer'),
    timerStart: state.get('ui').get('resetTimer').get('timerStart')
  }
};

export const ProgressBar = connect(mapStateToProps)(ProgressBar_Module);
Run Code Online (Sandbox Code Playgroud)

YaN*_*uSH 19

不要对宽度进行动画处理,而是尝试使用transform 和scaleX。以下是反应本机转换的一些参考: https://reactnative.dev/docs/transforms


Yos*_*ssi 9

按照@YaNuSH的建议,我只需要更换

   width: animatedValue
Run Code Online (Sandbox Code Playgroud)

和:

transform: [{ scaleX: scaling }],
Run Code Online (Sandbox Code Playgroud)

完整详细信息:

前:

Animated.timing(this.d_animation_width, {
      toValue: 175,
      duration: this.d_animation_progressTime,
      easing: Easing.linear
    }).start(()
Run Code Online (Sandbox Code Playgroud)

后:

Animated.timing(this.d_animation_width, {
      toValue: 175,
      duration: this.d_animation_progressTime,
      easing: Easing.linear,
      useNativeDriver: true
    }).start(()
Run Code Online (Sandbox Code Playgroud)

前:

return (
      <Animated.View
        style={[{
          position: 'absolute',
          left: 0,
          height: '150%',
          width: 0,
          zIndex: 1,
          backgroundColor: 'black',
        }, 
        {
          width: this.props.timer !== false ?
             this.d_animation_width : 175
        }]}
        onPress={this.props.onPress}
      >
      </Animated.View>
    )
Run Code Online (Sandbox Code Playgroud)

后:

const scaling = this.props.timer !== false ? this.d_animation_width : 175;

return (
  <Animated.View
    style={[
      {
        position: 'absolute',
        left: 0,
        height: '150%',
        width: 2,
        zIndex: 1,
        backgroundColor: 'black',
      },
      {
        transform: [
          {
            scaleX: scaling
          },
        ],
      },
    ]}
    onPress={this.props.onPress}
  >
  </Animated.View>
)
Run Code Online (Sandbox Code Playgroud)


小智 5

尝试这样做。

useNativeDriver: false
Run Code Online (Sandbox Code Playgroud)

它对我有用。

  • 这将导致动画在 JS 线程而不是 UI 线程上运行,这可能会导致丢帧。 (10认同)