Các đơn vị đo trong Android
Trong Android, có nhiều đơn vị đo khác nhau được sử dụng để định nghĩa kích thước và khoảng cách. Hiểu rõ các đơn vị này giúp bạn tạo ra giao diện hiển thị nhất quán trên nhiều thiết bị có độ phân giải và mật độ điểm ảnh khác nhau.
Tại sao không sử dụng Pixel (px)?
Mỗi màn hình có mật độ điểm ảnh (pixel density) khác nhau, do đó cùng một số lượng pixel sẽ hiển thị với kích thước vật lý khác nhau trên các thiết bị khác nhau.
Ví dụ, một View có chiều rộng 100 pixels:
- Trên thiết bị có mật độ thấp (160 dpi): hiển thị lớn
- Trên thiết bị có mật độ cao (480 dpi): hiển thị nhỏ hơn nhiều
Các đơn vị đo trong Android
1. dp (Density-independent Pixels)
dp là đơn vị được khuyến nghị sử dụng cho kích thước và khoảng cách trong layout.
- 1 dp tương đương khoảng 1 pixel trên màn hình có mật độ trung bình (160 dpi - gọi là “baseline density”)
- Android tự động chuyển đổi dp thành số pixel thực tế phù hợp với từng mật độ màn hình
- Giúp giao diện hiển thị với kích thước vật lý nhất quán trên các thiết bị khác nhau
Ví dụ sử dụng dp cho margin:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/clickme"
android:layout_marginTop="20dp" />2. sp (Scale-independent Pixels)
sp được sử dụng đặc biệt cho kích thước văn bản (text size).
- Mặc định, sp có cùng kích thước với dp
- Khác biệt: sp thay đổi theo cài đặt kích thước chữ mà người dùng chọn trong Settings
- Chỉ dùng sp cho text size, không dùng cho layout
Ví dụ sử dụng sp cho text size:
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp" />3. px (Pixels)
px là đơn vị pixel thực tế trên màn hình.
- Không được khuyến nghị sử dụng trong layout
- Kích thước hiển thị sẽ khác nhau trên các thiết bị có mật độ điểm ảnh khác nhau
- Chỉ nên dùng khi cần thao tác với bitmap hoặc canvas ở mức pixel
4. pt (Points)
- 1 pt = 1/72 inch dựa trên kích thước vật lý của màn hình
- Ít được sử dụng trong phát triển Android
5. mm (Millimeters)
- Dựa trên kích thước vật lý của màn hình (tính bằng millimeter)
- Ít được sử dụng
6. in (Inches)
- Dựa trên kích thước vật lý của màn hình (tính bằng inch)
- Ít được sử dụng
Công thức chuyển đổi dp sang pixel
px = dp × (dpi / 160)Ví dụ:
- Màn hình 160 dpi: 1 dp = 1 px
- Màn hình 240 dpi (hdpi): 1 dp = 1.5 px
- Màn hình 320 dpi (xhdpi): 1 dp = 2 px
- Màn hình 480 dpi (xxhdpi): 1 dp = 3 px
Chuyển đổi trong code
Sử dụng TypedValue.applyDimension() để chuyển đổi:
Kotlin:
val dpValue = 16f
val pxValue = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dpValue,
resources.displayMetrics
).toInt()Java:
float dpValue = 16f;
int pxValue = (int) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dpValue,
getResources().getDisplayMetrics()
);Các Density Bucket
Android phân loại các mật độ màn hình thành các nhóm (bucket):
| Qualifier | Mật độ (dpi) | Hệ số scale |
|---|---|---|
ldpi | ~120 dpi | 0.75x |
mdpi | ~160 dpi | 1.0x (baseline) |
hdpi | ~240 dpi | 1.5x |
xhdpi | ~320 dpi | 2.0x |
xxhdpi | ~480 dpi | 3.0x |
xxxhdpi | ~640 dpi | 4.0x |
Cách cung cấp hình ảnh cho các mật độ khác nhau
Để hình ảnh hiển thị đẹp trên mọi thiết bị, bạn nên cung cấp nhiều phiên bản với kích thước khác nhau theo tỷ lệ 3:4:6:8:12:16:
res/
drawable-ldpi/ # 36×36 (0.75x)
drawable-mdpi/ # 48×48 (1.0x baseline)
drawable-hdpi/ # 72×72 (1.5x)
drawable-xhdpi/ # 96×96 (2.0x)
drawable-xxhdpi/ # 144×144 (3.0x)
drawable-xxxhdpi/ # 192×192 (4.0x)Sử dụng Vector Graphics
Thay vì tạo nhiều phiên bản bitmap, bạn có thể sử dụng Vector Drawable - hình ảnh vector có thể scale mà không bị mờ:
res/
drawable/
ic_android_launcher.xmlVector graphics đặc biệt phù hợp cho icons và các hình minh họa đơn giản.
Thư mục mipmap cho App Icons
App icons nên được đặt trong thư mục mipmap thay vì drawable:
res/
mipmap-mdpi/
ic_launcher.png
mipmap-hdpi/
ic_launcher.png
mipmap-xhdpi/
ic_launcher.png
mipmap-xxhdpi/
ic_launcher.png
mipmap-xxxhdpi/
ic_launcher.pngTóm tắt Best Practices
| Đơn vị | Sử dụng cho | Ghi chú |
|---|---|---|
| dp | Layout (width, height, margin, padding) | ✅ Khuyến nghị |
| sp | Text size | ✅ Khuyến nghị cho text |
| px | Thao tác low-level với bitmap | ⚠️ Tránh dùng cho layout |
| pt, mm, in | Hiếm khi sử dụng | ❌ Không khuyến nghị |
Trong Jetpack Compose
Trong Compose, các đơn vị này được sử dụng thông qua extension:
// dp
Box(modifier = Modifier.size(100.dp))
// sp
Text(text = "Hello", fontSize = 16.sp)