Một giao diện hai cột trông ổn khi mở app nhưng vỡ sau khi xoay máy. Một cách sửa khác lại ép chữ nhỏ để mọi thứ nằm trong card. Cả hai đều làm mất mục tiêu chính: giao diện phải thích nghi với vùng hiển thị và cách người dùng đọc nội dung.
Bài này dùng useWindowDimensions để đổi bố cục theo chiều rộng cửa sổ, đồng thời để text tự xuống dòng và tôn trọng thiết lập chữ lớn. Tài liệu React Native được đối chiếu ngày 24/10/2026. Ví dụ đã được rà thủ công, chưa build hoặc kiểm tra trên thiết bị; cần thử với phiên bản React Native và hệ điều hành của dự án.
1. Đọc kích thước ở nơi component sử dụng
useWindowDimensions cập nhật kích thước cửa sổ và thông tin font scale khi chúng thay đổi. Điều đó phù hợp với component cần render lại theo môi trường hiện tại.
Một hằng lấy từ Dimensions.get('window') ở mức module chỉ giữ giá trị tại lần đọc đó. Theo tài liệu Dimensions, kích thước có thể đổi khi xoay màn hình hoặc trên thiết bị có vùng hiển thị thay đổi. Với component, hook giúp bạn nhận các cập nhật mà không tự quản lý listener cho trường hợp thông thường.
Chiều rộng cửa sổ không phải chiều rộng của mọi container con. Ví dụ sau giả định component được đặt trong một màn hình chiếm chiều rộng cửa sổ. Nếu nó nằm trong modal hẹp hoặc pane riêng, hãy đo vùng bố trí thực tế của container thay vì lấy breakpoint toàn cửa sổ áp cho mọi nơi.
2. Một component cho màn hình toàn chiều rộng
Component dưới đây là nội dung màn hình; đặt nó trong parent có chiều cao được giới hạn và flex: 1, bên trong vùng safe area mà app đã quản lý. Nó không tự cấu hình navigation hay safe area cho toàn ứng dụng.
import React from 'react';
import {
ScrollView,
StyleSheet,
Text,
View,
useWindowDimensions,
} from 'react-native';
export default function ResponsiveSummary() {
const {width, fontScale} = useWindowDimensions();
const wide = width >= 720;
return (
<ScrollView style={styles.screen} contentContainerStyle={styles.page}>
<Text style={styles.heading}>Tổng quan dự án</Text>
<Text style={styles.description}>
Nội dung được phép xuống dòng khi cửa sổ hẹp hoặc chữ lớn.
</Text>
<View style={[styles.cards, wide ? styles.row : styles.column]}>
<View style={[styles.card, wide && styles.wideCard]}>
<Text style={styles.title}>Việc đang xử lý</Text>
<Text style={styles.body}>
Kiểm tra lại mô tả dài bằng tiếng Việt trước khi gửi bản build.
</Text>
</View>
<View style={[styles.card, wide && styles.wideCard]}>
<Text style={styles.title}>Bước tiếp theo</Text>
<Text style={styles.body}>
Rà bố cục khi xoay màn hình và tăng cỡ chữ trong hệ thống.
</Text>
</View>
</View>
<Text style={styles.debug}>Font scale hiện tại: {fontScale}</Text>
</ScrollView>
);
}
const styles = StyleSheet.create({
screen: {flex: 1},
page: {width: '100%', maxWidth: 960, alignSelf: 'center', padding: 16},
heading: {fontSize: 24, fontWeight: '700', marginBottom: 12},
description: {fontSize: 16, marginBottom: 16},
cards: {alignItems: 'stretch'},
row: {flexDirection: 'row'},
column: {flexDirection: 'column'},
wideCard: {flex: 1},
card: {minWidth: 0, padding: 16, margin: 4,
backgroundColor: '#e8eef7', borderRadius: 12},
title: {fontSize: 18, fontWeight: '600', marginBottom: 8},
body: {fontSize: 16},
debug: {fontSize: 14, marginTop: 16},
});
Ngưỡng 720 là lựa chọn minh họa cho bố cục này, không phải định nghĩa tablet hoặc quy tắc bắt buộc của React Native. maxWidth giới hạn độ dài dòng khi cửa sổ rộng. minWidth: 0 cho phép card co lại trong hàng; text không bị buộc vào chiều cao cố định.
3. Giữ khả năng đọc khi chữ lớn
Theo tham chiếu Text, allowFontScaling mặc định bật để tôn trọng cỡ chữ từ thiết lập accessibility. Ví dụ không tắt nó và không chia fontSize cho fontScale để triệt tiêu lựa chọn của người dùng.
fontScale ở cuối chỉ là thông tin chẩn đoán; có thể bỏ dòng đó khi đưa vào sản phẩm. Đừng tự nhân mọi font với fontScale mà không hiểu component đang xử lý scale thế nào. Trước tiên, cho phép dòng chữ cao hơn, card giãn theo nội dung và màn hình cuộn được.
Không đặt numberOfLines chỉ để giấu phần tràn của nội dung quan trọng. Nếu sản phẩm cần rút gọn, hãy thiết kế đường mở nội dung đầy đủ và kiểm tra trải nghiệm đọc. Một card nằm gọn nhưng mất chỉ dẫn chính vẫn là lỗi giao diện.
Kiểm tra bằng một ma trận nhỏ
Thử portrait và landscape trên cửa sổ hẹp. Sau đó tăng cỡ chữ hệ thống, dùng chuỗi tiếng Việt dài hơn ví dụ và kiểm tra cuộn tới nội dung cuối. Nếu nền tảng cho phép split-screen hoặc thay đổi vùng hiển thị, thêm trường hợp đó vào bộ kiểm tra.
Ở mỗi ca, xác nhận layout đổi mà không cần mở lại app, tiêu đề không đè nội dung, text không bị cắt và card còn đọc được. Ngưỡng hai cột có thể cần tăng hoặc thay đổi chính sách theo kết quả thực tế. Hook cung cấp số liệu; nó không tự quyết định bố cục tốt cho nội dung của bạn.
Lỗi thường gặp
Nếu kích thước không cập nhật, tìm các giá trị được cache ngoài component. Nếu layout trong modal sai dù width đúng, kiểm tra bạn đang dùng chiều rộng cửa sổ cho một container nhỏ hơn hay không. Nếu không cuộn, kiểm tra chuỗi parent có ràng buộc chiều cao và flex: 1 phù hợp.
Nếu chữ lớn làm card mất nội dung, bỏ chiều cao cố định và các giới hạn số dòng không cần thiết trước khi nghĩ đến thu nhỏ font. Với màn hình có nhiều dữ liệu hơn ví dụ, tiếp tục đánh giá component danh sách và cấu trúc điều hướng; ScrollView nhỏ này không thay thế thiết kế cho danh sách dài.
Kết luận
Dùng kích thước hiện tại để chọn bố cục, rồi kiểm tra bằng nội dung và cỡ chữ thực tế. Responsive tốt cần cả vùng hiển thị lẫn khả năng đọc; một breakpoint đơn lẻ chưa đủ chứng minh màn hình đã thích nghi.




