mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-03-06 22:39:41 +08:00
fix: make sure we don't miss dimensions updates
This commit is contained in:
31
packages/bottom-tabs/src/utils/useIsKeyboardShown.tsx
Normal file
31
packages/bottom-tabs/src/utils/useIsKeyboardShown.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import * as React from 'react';
|
||||
import { Keyboard, Platform } from 'react-native';
|
||||
|
||||
export default function useIsKeyboardShown() {
|
||||
const [isKeyboardShown, setIsKeyboardShown] = React.useState(false);
|
||||
|
||||
React.useEffect(() => {
|
||||
const handleKeyboardShow = () => setIsKeyboardShown(true);
|
||||
const handleKeyboardHide = () => setIsKeyboardShown(false);
|
||||
|
||||
if (Platform.OS === 'ios') {
|
||||
Keyboard.addListener('keyboardWillShow', handleKeyboardShow);
|
||||
Keyboard.addListener('keyboardWillHide', handleKeyboardHide);
|
||||
} else {
|
||||
Keyboard.addListener('keyboardDidShow', handleKeyboardShow);
|
||||
Keyboard.addListener('keyboardDidHide', handleKeyboardHide);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (Platform.OS === 'ios') {
|
||||
Keyboard.removeListener('keyboardWillShow', handleKeyboardShow);
|
||||
Keyboard.removeListener('keyboardWillHide', handleKeyboardHide);
|
||||
} else {
|
||||
Keyboard.removeListener('keyboardDidShow', handleKeyboardShow);
|
||||
Keyboard.removeListener('keyboardDidHide', handleKeyboardHide);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return isKeyboardShown;
|
||||
}
|
||||
37
packages/bottom-tabs/src/utils/useWindowDimensions.tsx
Normal file
37
packages/bottom-tabs/src/utils/useWindowDimensions.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import * as React from 'react';
|
||||
import { ScaledSize, Dimensions } from 'react-native';
|
||||
|
||||
// This is similar to the new useWindowDimensions hook in react-native
|
||||
// However, we have a custom implementation to support older RN versions
|
||||
export default function useWindowDimensions() {
|
||||
const [dimensions, setDimensions] = React.useState(() => {
|
||||
// `height` and `width` maybe undefined during SSR, so we initialize them
|
||||
const { height = 0, width = 0 } = Dimensions.get('window');
|
||||
|
||||
return { height, width };
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
const onChange = ({ window }: { window: ScaledSize }) => {
|
||||
const { width, height } = window;
|
||||
|
||||
setDimensions((d) => {
|
||||
if (width === d.width && height === d.height) {
|
||||
return d;
|
||||
}
|
||||
|
||||
return { width, height };
|
||||
});
|
||||
};
|
||||
|
||||
// We might have missed an update before the listener was added
|
||||
// So make sure to update the dimensions
|
||||
onChange({ window: Dimensions.get('window') });
|
||||
|
||||
Dimensions.addEventListener('change', onChange);
|
||||
|
||||
return () => Dimensions.addEventListener('change', onChange);
|
||||
}, []);
|
||||
|
||||
return dimensions;
|
||||
}
|
||||
@@ -3,11 +3,8 @@ import {
|
||||
View,
|
||||
Animated,
|
||||
StyleSheet,
|
||||
Keyboard,
|
||||
Platform,
|
||||
LayoutChangeEvent,
|
||||
ScaledSize,
|
||||
Dimensions,
|
||||
} from 'react-native';
|
||||
import {
|
||||
NavigationContext,
|
||||
@@ -19,6 +16,8 @@ import {
|
||||
import { useSafeArea } from 'react-native-safe-area-context';
|
||||
|
||||
import BottomTabItem from './BottomTabItem';
|
||||
import useWindowDimensions from '../utils/useWindowDimensions';
|
||||
import useIsKeyboardShown from '../utils/useIsKeyboardShown';
|
||||
import type { BottomTabBarProps } from '../types';
|
||||
|
||||
type Props = BottomTabBarProps & {
|
||||
@@ -57,7 +56,8 @@ export default function BottomTabBar({
|
||||
const focusedDescriptor = descriptors[focusedRoute.key];
|
||||
const focusedOptions = focusedDescriptor.options;
|
||||
|
||||
const [isKeyboardShown, setIsKeyboardShown] = React.useState(false);
|
||||
const dimensions = useWindowDimensions();
|
||||
const isKeyboardShown = useIsKeyboardShown();
|
||||
|
||||
const shouldShowTabBar =
|
||||
focusedOptions.tabBarVisible !== false &&
|
||||
@@ -91,43 +91,6 @@ export default function BottomTabBar({
|
||||
}
|
||||
}, [shouldShowTabBar, visible]);
|
||||
|
||||
const [dimensions, setDimensions] = React.useState(() => {
|
||||
const { height = 0, width = 0 } = Dimensions.get('window');
|
||||
|
||||
return { height, width };
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
const handleOrientationChange = ({ window }: { window: ScaledSize }) => {
|
||||
setDimensions(window);
|
||||
};
|
||||
|
||||
Dimensions.addEventListener('change', handleOrientationChange);
|
||||
|
||||
const handleKeyboardShow = () => setIsKeyboardShown(true);
|
||||
const handleKeyboardHide = () => setIsKeyboardShown(false);
|
||||
|
||||
if (Platform.OS === 'ios') {
|
||||
Keyboard.addListener('keyboardWillShow', handleKeyboardShow);
|
||||
Keyboard.addListener('keyboardWillHide', handleKeyboardHide);
|
||||
} else {
|
||||
Keyboard.addListener('keyboardDidShow', handleKeyboardShow);
|
||||
Keyboard.addListener('keyboardDidHide', handleKeyboardHide);
|
||||
}
|
||||
|
||||
return () => {
|
||||
Dimensions.removeEventListener('change', handleOrientationChange);
|
||||
|
||||
if (Platform.OS === 'ios') {
|
||||
Keyboard.removeListener('keyboardWillShow', handleKeyboardShow);
|
||||
Keyboard.removeListener('keyboardWillHide', handleKeyboardHide);
|
||||
} else {
|
||||
Keyboard.removeListener('keyboardDidShow', handleKeyboardShow);
|
||||
Keyboard.removeListener('keyboardDidHide', handleKeyboardHide);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
const [layout, setLayout] = React.useState({
|
||||
height: 0,
|
||||
width: dimensions.width,
|
||||
|
||||
37
packages/drawer/src/utils/useWindowDimensions.tsx
Normal file
37
packages/drawer/src/utils/useWindowDimensions.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import * as React from 'react';
|
||||
import { ScaledSize, Dimensions } from 'react-native';
|
||||
|
||||
// This is similar to the new useWindowDimensions hook in react-native
|
||||
// However, we have a custom implementation to support older RN versions
|
||||
export default function useWindowDimensions() {
|
||||
const [dimensions, setDimensions] = React.useState(() => {
|
||||
// `height` and `width` maybe undefined during SSR, so we initialize them
|
||||
const { height = 0, width = 0 } = Dimensions.get('window');
|
||||
|
||||
return { height, width };
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
const onChange = ({ window }: { window: ScaledSize }) => {
|
||||
const { width, height } = window;
|
||||
|
||||
setDimensions((d) => {
|
||||
if (width === d.width && height === d.height) {
|
||||
return d;
|
||||
}
|
||||
|
||||
return { width, height };
|
||||
});
|
||||
};
|
||||
|
||||
// We might have missed an update before the listener was added
|
||||
// So make sure to update the dimensions
|
||||
onChange({ window: Dimensions.get('window') });
|
||||
|
||||
Dimensions.addEventListener('change', onChange);
|
||||
|
||||
return () => Dimensions.addEventListener('change', onChange);
|
||||
}, []);
|
||||
|
||||
return dimensions;
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
import * as React from 'react';
|
||||
import {
|
||||
View,
|
||||
Dimensions,
|
||||
StyleSheet,
|
||||
I18nManager,
|
||||
Platform,
|
||||
ScaledSize,
|
||||
BackHandler,
|
||||
NativeEventSubscription,
|
||||
} from 'react-native';
|
||||
@@ -25,6 +23,7 @@ import DrawerContent from './DrawerContent';
|
||||
import Drawer from './Drawer';
|
||||
import DrawerOpenContext from '../utils/DrawerOpenContext';
|
||||
import DrawerPositionContext from '../utils/DrawerPositionContext';
|
||||
import useWindowDimensions from '../utils/useWindowDimensions';
|
||||
import type {
|
||||
DrawerDescriptorMap,
|
||||
DrawerNavigationConfig,
|
||||
@@ -86,9 +85,7 @@ export default function DrawerView({
|
||||
sceneContainerStyle,
|
||||
}: Props) {
|
||||
const [loaded, setLoaded] = React.useState([state.index]);
|
||||
const [dimensions, setDimensions] = React.useState(() =>
|
||||
Dimensions.get('window')
|
||||
);
|
||||
const dimensions = useWindowDimensions();
|
||||
|
||||
const { colors } = useTheme();
|
||||
|
||||
@@ -133,16 +130,6 @@ export default function DrawerView({
|
||||
return () => subscription?.remove();
|
||||
}, [handleDrawerClose, isDrawerOpen, navigation, state.key]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const updateDimensions = ({ window }: { window: ScaledSize }) => {
|
||||
setDimensions(window);
|
||||
};
|
||||
|
||||
Dimensions.addEventListener('change', updateDimensions);
|
||||
|
||||
return () => Dimensions.removeEventListener('change', updateDimensions);
|
||||
}, []);
|
||||
|
||||
if (!loaded.includes(state.index)) {
|
||||
setLoaded([...loaded, state.index]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user