样式属性“width”不受本机动画模块支持:需要重写代码的建议

17

我继承了以下组件,它在之前的react-native版本中工作正常,在其他组件中显示不透明的滚动进度条按钮。

最近,当我升级到 react-native 0.62.2时,出现了一个错误要求添加 useNativeDriver。当将其添加并设置为“是”时,我收到一个错误,指出“width 样式属性不受本地动画模块支持。”

当将 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);
4个回答

37

试着做这件事。

useNativeDriver: false

对我有用。


9
这将导致动画在 JS 线程上运行,而不是 UI 线程上运行,可能会导致帧率下降。 - Thijs

19

1
这确实是正确的方法。我已经发布了另一个带有详细信息的答案。 - Yossi
如果初始宽度和高度从0开始,我该怎么办? - Suresh Murali
@SureshMurali,我认为在您的应用程序中将初始宽度设置为最大值会更好。这样,当您使用变换时,您就知道scaleX:0将是宽度为0,scaleX:0.5将是宽度/2等等... - YaNuSH
但是根据我的设计,我想通过设置宽度为0来使其不可见。还有其他解决方案吗? - Suresh Murali
我不明白为什么你不能将scaleX设置为0而不是将宽度设置为0。 - YaNuSH

7

遵循 @YaNuSH 的建议,我只需要替换

   width: animatedValue

使用:

transform: [{ scaleX: scaling }],

完整细节:

之前:

Animated.timing(this.d_animation_width, {
      toValue: 175,
      duration: this.d_animation_progressTime,
      easing: Easing.linear
    }).start(()

之后:

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

before:

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 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>
)

0
Animated.timing(this.loadingValue.width, {
        toValue: widthEnd,
        duration: 400,
        useNativeDriver: false //add this line into the library
      }).start();

      Animated.timing(this.loadingValue.borderRadius, {
        toValue: borderRadiusEnd,
        duration: 400,
        useNativeDriver: false //add this line into the library
      }).start();

      Animated.timing(this.loadingValue.opacity, {
        toValue: opacityEnd,
        duration: 300,
        useNativeDriver: false //add this line into the library
      }).start();

那就这样吧...享受你的编码吧...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接