Safe Area и адаптивность
Мобильные экраны отличаются: «челка», домашняя кнопка, разные размеры. Нужно адаптироваться.
Safe Area
Safe Area — область экрана, не перекрытая системными элементами.
npx expo install react-native-safe-area-context
import { SafeAreaView } from 'react-native-safe-area-context';
<SafeAreaView style={{ flex: 1 }} edges={['top', 'bottom']}>
{/* контент */}
</SafeAreaView>
edges:
'top'— сверху (челка, статус-бар)'bottom'— снизу (домашняя кнопка)'left','right'— по бокам['top', 'bottom']— комбинация
useSafeAreaInsets
Для точных отступов:
import { useSafeAreaInsets } from 'react-native-safe-area-context';
function Screen() {
const insets = useSafeAreaInsets();
return (
<View style={{ paddingTop: insets.top, paddingBottom: insets.bottom }}>
{/* контент */}
</View>
);
}
Dimensions
Размеры экрана:
import { Dimensions } from 'react-native';
const { width, height } = Dimensions.get('window');
При повороте экрана — слушать изменения:
import { useWindowDimensions } from 'react-native';
function Screen() {
const { width, height } = useWindowDimensions();
return (
<View style={{ width: width - 32 }}>
{/* контент */}
</View>
);
}
useWindowDimensions — предпочтительно. Обновляется автоматически.
Проценты
<View style={{ width: '50%', height: '100%' }} />
Работает для ширины и высоты, но не для отступов.
Условные стили по ширине
function Screen() {
const { width } = useWindowDimensions();
const isTablet = width >= 768;
return (
<View style={[styles.container, isTablet && styles.tablet]}>
{/* контент */}
</View>
);
}
PixelRatio
import { PixelRatio } from 'react-native';
PixelRatio.get(); // 2 на iPhone, 3 на Pro
PixelRatio.getFontScale(); // масштаб шрифта пользователя
Не нужно для большинства случаев — React Native сам адаптируется.
Статус-бар
import { StatusBar } from 'expo-status-bar';
<StatusBar style="auto" />
<StatusBar style="light" />
<StatusBar style="dark" />
<StatusBar hidden />
Адаптивность
const { width } = useWindowDimensions();
const cardWidth = width < 375 ? '100%' : '48%';
Или через flexWrap:
<View style={{ flexDirection: 'row', flexWrap: 'wrap', gap: 12 }}>
{items.map((item) => (
<View key={item.id} style={{ width: '48%' }}>
{/* карточка */}
</View>
))}
</View>
Клавиатура и safe area
<SafeAreaView style={{ flex: 1 }}>
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={{ flex: 1 }}
>
{/* форма */}
</KeyboardAvoidingView>
</SafeAreaView>
Ориентация
В app.json:
{
"expo": {
"orientation": "portrait"
}
}
Варианты: default, portrait, landscape.
Если ты уже знаешь React
В вебе — медиазапросы и vw/vh. В React Native — useWindowDimensions, проценты, SafeAreaView. Нельзя просто написать CSS-медиазапрос.
Итоги
SafeAreaViewдля системных элементовuseSafeAreaInsetsдля точных отступовuseWindowDimensionsдля адаптивности- Проценты для ширины
app.jsonдля ориентации