获取 Animated.Value 的当前值,React-native

IT技术 reactjs react-native react-native-android
2021-05-03 03:22:51

我正在尝试使用插值为 View 设置动画。我想获得我的 Animated.Value 的当前值,但不知道如何。我不明白如何使用React-native docs做到这一点

this.state = {
      translateAnim: new Animated.Value(0)
}
DeviceEventEmitter.addListener('Accelerometer', function (data) {
  console.log(this.state.translateAnim);
  // returns an object, but I need a value in current moment
}
4个回答

我发现,如何获得value:

this.state.translateAnim.addListener(({value}) => this._value = value);

编辑

要记录一个值,我执行以下操作:

console.log(this.state.translateAnim._value)

这也适用于我...

const headerHeight = new Animated.Value(0);

经过一些操作......

console.log(headerHeight.__getValue())

感觉很hackish,但它完成了工作......

对于有typescript的人。

console.log((this.state.translateAnim as any)._value);

它对我来说完全 tsc 任何工作。

编辑:注意 - 可能会导致严重的性能问题。我一直无法弄清楚原因,但是如果您将它用于 30 多个同步动画,您的帧速率将慢到爬行。似乎它必须是 Animated.Value addListener 的 react-native 中的一个错误,因为我没有发现我的代码有任何问题,它只设置了一个侦听器,该侦听器设置了一个应该是即时的 ref。

这是我想出的一个钩子,不需要访问私有内部值就可以做到这一点。

/**
 * Since there's no (official) way to read an Animated.Value synchronously this is the best solution I could come up with
 * to have access to an up-to-date copy of the latest value without sacrificing performance.
 * 
 * @param animatedValue the Animated.Value to track
 * @param initial Optional initial value if you know it to initialize the latest value ref before the animated value listener fires for the first time
 *
 * returns a ref with the latest value of the Animated.Value and a boolean ref indicating if a value has been received yet
 */
const useAnimatedLatestValueRef = (animatedValue: Animated.Value, initial?: number) => {
    //If we're given an initial value then we can pretend we've received a value from the listener already
    const latestValueRef = useRef(initial ?? 0)
    const initialized = useRef(typeof initial == "number")

    useEffect(() => {
        const id = animatedValue.addListener((v) => {
            //Store the latest animated value
            latestValueRef.current = v.value
            //Indicate that we've recieved a value
            initialized.current = true
        })

        //Return a deregister function to clean up
        return () => animatedValue.removeListener(id)

        //Note that the behavior here isn't 100% correct if the animatedValue changes -- the returned ref
        //may refer to the previous animatedValue's latest value until the new listener returns a value
    }, [animatedValue])


    return [latestValueRef, initialized] as const
}