Skip to content

Commit

Permalink
Use constant value for translation when DrawerLayout is idle (#2005)
Browse files Browse the repository at this point in the history
Fixes #386.

`AnimatedInterpolation` was causing problems on Android when the activity was paused for some reason (like permission or share dialog). For some reason it was changing its value on pause, opening the drawer, and again on resume closing the drawer. This PR changes `DrawerLayout` so that it uses constant value instead of interpolation when the drawer is idle.
  • Loading branch information
j-piasecki authored Apr 27, 2022
1 parent 3fc9b45 commit 68f02ac
Showing 1 changed file with 29 additions and 10 deletions.
39 changes: 29 additions & 10 deletions src/components/DrawerLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,8 @@ export type DrawerLayoutState = {
touchX: Animated.Value;
drawerTranslation: Animated.Value;
containerWidth: number;
drawerState: DrawerState;
drawerOpened: boolean;
};

export type DrawerMovementOption = {
Expand Down Expand Up @@ -189,6 +191,8 @@ export default class DrawerLayout extends Component<
touchX,
drawerTranslation,
containerWidth: 0,
drawerState: IDLE,
drawerOpened: false,
};

this.updateAnimatedEvent(props, this.state);
Expand Down Expand Up @@ -349,6 +353,7 @@ export default class DrawerLayout extends Component<
this.handleRelease({ nativeEvent });
} else if (nativeEvent.state === State.ACTIVE) {
this.emitStateChanged(DRAGGING, false);
this.setState({ drawerState: DRAGGING });
if (this.props.keyboardDismissMode === 'on-drag') {
Keyboard.dismiss();
}
Expand Down Expand Up @@ -464,6 +469,7 @@ export default class DrawerLayout extends Component<
const willShow = toValue !== 0;
this.updateShowing(willShow);
this.emitStateChanged(SETTLING, willShow);
this.setState({ drawerState: SETTLING });
if (this.props.hideStatusBar) {
StatusBar.setHidden(willShow, this.props.statusBarAnimation || 'slide');
}
Expand All @@ -476,6 +482,12 @@ export default class DrawerLayout extends Component<
}).start(({ finished }) => {
if (finished) {
this.emitStateChanged(IDLE, willShow);
this.setState({ drawerOpened: willShow });
if (this.state.drawerState !== DRAGGING) {
// it's possilbe that user started drag while the drawer
// was settling, don't override state in this case
this.setState({ drawerState: IDLE });
}
if (willShow) {
this.props.onDrawerOpen?.();
} else {
Expand Down Expand Up @@ -516,11 +528,14 @@ export default class DrawerLayout extends Component<
private renderOverlay = () => {
/* Overlay styles */
invariant(this.openValue, 'should be set');
const overlayOpacity = this.openValue.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
extrapolate: 'clamp',
});
let overlayOpacity;

if (this.state.drawerState !== IDLE) {
overlayOpacity = this.openValue;
} else {
overlayOpacity = this.state.drawerOpened ? 1 : 0;
}

const dynamicOverlayStyles = {
opacity: overlayOpacity,
backgroundColor: this.props.overlayColor,
Expand Down Expand Up @@ -579,11 +594,15 @@ export default class DrawerLayout extends Component<
let drawerTranslateX: number | Animated.AnimatedInterpolation = 0;
if (drawerSlide) {
const closedDrawerOffset = fromLeft ? -drawerWidth! : drawerWidth!;
drawerTranslateX = openValue.interpolate({
inputRange: [0, 1],
outputRange: [closedDrawerOffset, 0],
extrapolate: 'clamp',
});
if (this.state.drawerState !== IDLE) {
drawerTranslateX = openValue.interpolate({
inputRange: [0, 1],
outputRange: [closedDrawerOffset, 0],
extrapolate: 'clamp',
});
} else {
drawerTranslateX = this.state.drawerOpened ? 0 : closedDrawerOffset;
}
}
const drawerStyles: {
transform: { translateX: number | Animated.AnimatedInterpolation }[];
Expand Down

0 comments on commit 68f02ac

Please sign in to comment.