O'lchamlar — useWindowDimensions, foizlar, turli ekranlar
Muammodan boshlaylik
Ilova sizning telefoningizda chiroyli. Do'stingizning kichik Android telefonida esa tugmalar ekrandan chiqib ketgan. Planshetda — hamma narsa ulkan, ekranning yarmi bo'sh. Telefonni yonboshlab burishganda — layout buzildi.
Ekranlar 320 dan 1000+ birlik kenglikkacha. Ilova hammasida yaxshi ko'rinishi kerak.
Qattiq raqamlardan qoching
// ❌ 400 kenglikdagi telefonda ishlaydi, 360 da — chiqib ketadi
<View style={{ width: 380 }} />
// ✅ Moslashuvchan
<View style={{ width: '100%' }} />
<View style={{ flex: 1 }} />
<View style={{ alignSelf: 'stretch', marginHorizontal: 16 }} />
Qoida: konteyner kengliklari — flex, foizlar va padding. Qattiq raqamlar — faqat kichik elementlar uchun (ikonka, avatar, tugma balandligi).
useWindowDimensions — ekran o'lchami
import { useWindowDimensions } from 'react-native';
export default function Ekran() {
const { width, height, fontScale } = useWindowDimensions();
// width — 390, height — 844 (masalan)
}
Hook — ekran burilganda yoki oyna o'lchami o'zgarganda (planshetda split-screen) avtomatik yangilanadi va komponent qayta chiziladi.
[!INFO] Eski kodda
Dimensions.get('window')ni ko'rasiz. U faqat bir marta o'qiladi va burilishni sezmaydi. Komponent ichida doimuseWindowDimensionsishlating.
Kenglikka moslashgan grid
const { width } = useWindowDimensions();
const ustunlar = width >= 768 ? 4 : width >= 500 ? 3 : 2;
const bo_shliq = 12;
const kartaKengligi = (width - 16 * 2 - bo_shliq * (ustunlar - 1)) / ustunlar;
Telefonda — 2 ustun, katta telefonda yonboshlab — 3, planshetda — 4.
Karusel — ekran kengligida
const { width } = useWindowDimensions();
<ScrollView horizontal pagingEnabled>
{bannerlar.map((b) => (
<Image key={b.id} source={{ uri: b.rasm }} style={{ width, height: width * 0.5 }} />
))}
</ScrollView>
Banner balandligi — kenglikning yarmi: har qanday ekranda nisbat saqlanadi. Bu ham aspectRatio: 2 bilan qilish mumkin (7-dars).
Planshetlar
const { width } = useWindowDimensions();
const planshet = width >= 768;
<View style={{ flex: 1, flexDirection: planshet ? 'row' : 'column' }}>
<View style={{ flex: planshet ? 1 : undefined }}>
<RoyxatEkran />
</View>
{planshet && (
<View style={{ flex: 2 }}>
<TafsilotEkran />
</View>
)}
</View>
Telefonda — ro'yxat, bosilganda tafsilot alohida ekranda. Planshetda — ro'yxat chapda, tafsilot o'ngda (master-detail).
Juda keng ekranda kontentni cheklash
<View style={{ flex: 1, alignItems: 'center' }}>
<View style={{ width: '100%', maxWidth: 600, padding: 16 }}>
{/* forma */}
</View>
</View>
Planshetda forma 1000 birlik kenglikka cho'zilmaydi.
Ekran yo'nalishi
app.json da:
"orientation": "portrait"
| Qiymat | Ma'nosi |
|---|---|
portrait |
Faqat tik (ko'pchilik ilovalar) |
landscape |
Faqat yotiq (o'yinlar, video) |
default |
Ikkalasi ham |
Ko'p ilovalar portrait bilan cheklanadi — bu qonuniy va oddiy tanlov. Planshet uchun alohida ilova bo'lsa — default va moslashuvchan layout.
Shrift o'lchami — foydalanuvchi sozlamasi
Ko'p foydalanuvchilar (ayniqsa yoshi kattalar) tizim sozlamalarida shriftni kattalashtiradi. React Native Text ni avtomatik kattalashtiradi — bu yaxshi. Lekin dizayn buzilishi mumkin:
// Matnning maksimal kattalashuvini cheklash (butunlay o'chirmang!)
<Text maxFontSizeMultiplier={1.5}>Tugma matni</Text>
const { fontScale } = useWindowDimensions(); // 1 — standart, 1.3 — kattalashtirilgan
Sinab ko'ring: telefon sozlamalarida eng katta shriftni yoqing va ilovani tekshiring. Tugmalarga qattiq height emas, paddingVertical + minHeight bering — matn kattalashganda tugma ham o'ssin.
[!WARNING]
allowFontScaling={false}bilan kattalashuvni butunlay o'chirish — ko'rish qobiliyati past foydalanuvchilarga nisbatan adolatsiz va do'konlar ko'rib chiqishida ham salbiy. Cheklang (maxFontSizeMultiplier), lekin o'chirmang.
PixelRatio — chegaralar va rasmlar
import { PixelRatio, StyleSheet } from 'react-native';
PixelRatio.get(); // 3 — iPhone, 2.625 — ko'p Android
StyleSheet.hairlineWidth; // eng ingichka chiziq: 1 / PixelRatio
<View style={{ borderBottomWidth: StyleSheet.hairlineWidth, borderColor: '#e2e8f0' }} />
Ro'yxat bandlari orasidagi nozik ajratuvchi chiziq — iOS ilovalaridagidek.
Turli ekranlarda sinash
- Kichik ekran: Android emulyatorda "Pixel 4a" yoki 5 dyuymli qurilma
- Katta ekran va planshet: "Pixel Tablet", iPad simulator
- Yotiq holat: emulyatorni burish
- Katta shrift: tizim sozlamalari
- Expo Go dan veb versiyasini ochib (
w), brauzer oynasi o'lchamini o'zgartirish — tez tekshiruv
Nima uchun shunday?
Nima uchun React Native da CSS media query lar yo'q?
Media query — statik qoida: "shu kenglikdan katta bo'lsa, shu stil". React Native da esa layout JavaScript da hisoblanadi, va useWindowDimensions sizga o'lchamni oddiy o'zgaruvchi sifatida beradi. Bu media query dan kuchliroq: o'lchamga qarab nafaqat stilni, balki komponentlarni ham almashtirish mumkin (planshetda master-detail, telefonda alohida ekranlar). Shart — oddiy if.
Xulosa
Eslab qoling:
- Konteynerlar —
flex,%,padding; qattiq raqamlar — faqat kichik elementlar uchun useWindowDimensions()— burilish va o'lcham o'zgarishida yangilanadi;Dimensions.getemas- Kenglikka qarab ustunlar soni va layout (telefon / planshet)
maxWidth— keng ekranda kontentni cheklashorientation—app.jsonda- Foydalanuvchi shrift o'lchami:
maxFontSizeMultiplier, tugmalargaminHeight StyleSheet.hairlineWidth— nozik chiziq
Keyingi dars
16-dars: Platform — Android va iOS farqlari, soyalar