Fix NavigationCardStackPanResponder to work with native animations

Summary:
`NavigationCardStackPanResponder` uses `__getValue` and the `stopAnimation` callback value which both doesn't work with native driven animation. The workaround here is to add a value listener so the JS value of the AnimatedValue gets updated too so `__getValue` has a relatively up to date value. This value should be good unless JS lags behind native a lot but that should not happen during a navigation gesture. Also added a comment that explains the hack.

**Test plan**
Tested in an app that uses native driven animations with a back gesture. This also needs #10643 and #10641 for everything to work properly.
Closes https://github.com/facebook/react-native/pull/10642

Differential Revision: D4135496

Pulled By: ericvicenti

fbshipit-source-id: 395aff78b16a37ad9407207a05504fdd6311f733
This commit is contained in:
Janic Duplessis 2016-11-04 20:35:48 -07:00 committed by Facebook Github Bot
parent 97d90a1d71
commit ac19276534

View File

@ -22,6 +22,8 @@ import type {
NavigationSceneRendererProps,
} from 'NavigationTypeDefinition';
const emptyFunction = () => {};
/**
* The duration of the card animation in milliseconds.
*/
@ -92,6 +94,17 @@ class NavigationCardStackPanResponder extends NavigationAbstractPanResponder {
this._isVertical = direction === Directions.VERTICAL;
this._props = props;
this._startValue = 0;
// Hack to make this work with native driven animations. We add a single listener
// so the JS value of the following animated values gets updated. We rely on
// some Animated private APIs and not doing so would require using a bunch of
// value listeners but we'd have to remove them to not leak and I'm not sure
// when we'd do that with the current structure we have. `stopAnimation` callback
// is also broken with native animated values that have no listeners so if we
// want to remove this we have to fix this too.
this._addNativeListener(this._props.layout.width);
this._addNativeListener(this._props.layout.height);
this._addNativeListener(this._props.position);
}
onMoveShouldSetPanResponder(event: any, gesture: any): boolean {
@ -210,6 +223,16 @@ class NavigationCardStackPanResponder extends NavigationAbstractPanResponder {
}
).start();
}
_addNativeListener(animatedValue) {
if (!animatedValue.__isNative) {
return;
}
if (Object.keys(animatedValue._listeners).length === 0) {
animatedValue.addListener(emptyFunction);
}
}
}
function createPanHandlers(