Skip to content

Commit

Permalink
Fix NavigationCardStackPanResponder to work with native animations
Browse files Browse the repository at this point in the history
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 #10642

Differential Revision: D4135496

Pulled By: ericvicenti

fbshipit-source-id: 395aff78b16a37ad9407207a05504fdd6311f733
  • Loading branch information
janicduplessis authored and Facebook Github Bot committed Nov 5, 2016
1 parent 97d90a1 commit ac19276
Showing 1 changed file with 23 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import type {
NavigationSceneRendererProps,
} from 'NavigationTypeDefinition';

const emptyFunction = () => {};

/**
* The duration of the card animation in milliseconds.
*/
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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(
Expand Down

0 comments on commit ac19276

Please sign in to comment.