sp — Scale-independent Pixels, satuan ukuran teks di Android yang memperhitungkan pengaturan ukuran font di perangkat. Tidak seperti dp, sp ikut berskala dengan ukuran font sistem, memastikan aksesibilitas antarmuka. Artikel menjelaskan perbedaan antara sp dan dp, menunjukkan konfigurasi textSize di XML dan Kotlin, serta mengungkap praktik terbaik bekerja dengan tipografi di Android.
Poin Utama
sp (scale-independent pixel) — satuan ukuran ukuran font di Android yang secara otomatis berskala sesuai dengan pengaturan sistem pengguna. Ketika pemilik perangkat meningkatkan ukuran font di pengaturan, semua elemen dengan nilai sp akan bertambah secara proporsional. Ini memastikan aksesibilitas antarmuka bagi orang dengan penglihatan lemah.
Rasio dasar: 1 sp = 1 dp pada skala font standar 1.0 (normal). Jika pengguna mengatur font Large (1.15×), 16 sp berubah menjadi 18.4 piksel fisik. Pada ukuran font Small (0.85×), 16 sp yang sama akan menjadi 13.6 px. Mekanisme penskalaan dikelola melalui Settings.System.FONT_SCALE di tingkat Android Framework.
Menurut Google Material Design Guidelines, teks harus diatur secara eksklusif dalam sp. Pengecualian — label tetap di komponen di mana ukuran penting untuk tata letak (misalnya, teks di dalam tombol dengan tinggi tetap). Dalam kasus seperti itu, disarankan menggunakan dp dengan kontrol aksesibilitas manual.
Perbedaan antara sp dan dp — salah satu topik pertanyaan paling umum dalam wawancara pengembang Android dan dalam code review nyata. Kedua satuan terkait dengan density-independent pixel (160 dpi = 1 dp = 1 px di layar mdpi), tetapi berperilaku berbeda saat ukuran font sistem berubah.
| Karakteristik | sp | dp |
|---|---|---|
| Tujuan | Ukuran teks | Ukuran elemen, jarak, lebar, tinggi |
| Skala terhadap font | Ya (scale factor) | Tidak |
| Skala terhadap kerapatan | Ya | Ya |
| API untuk pengaturan | android:textSize | android:layout_width, layout_height, padding, margin |
| Material Design Token | typescale | spacing, sizing |
Dalam praktiknya kesalahan — menggunakan dp untuk teks. Jika teks diatur dalam dp, ia tidak akan berskala saat font diperbesar, membuat antarmuka tidak dapat diakses oleh pengguna dengan penglihatan lemah. Kesalahan sebaliknya — menggunakan sp untuk tinggi tombol atau jarak: saat font diperbesar, tombol bisa „menggembung", merusak tata letak.
Penskalaan sp diimplementasikan di tingkat Android Framework dalam kelas TypedValue. Rumus perhitungan ulang: sp = dp × scaledDensity, di mana scaledDensity adalah koefisien skala yang memperhitungkan baik kerapatan layar maupun pengaturan font pengguna.
// Mendapatkan scaledDensity secara terprogram di Kotlin
val scaledDensity = with(context.resources) {
displayMetrics.scaledDensity
}
// Mengonversi sp ke px
fun spToPx(sp: Float, context: Context): Float {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP,
sp,
context.resources.displayMetrics
)
}
// Mengonversi px ke sp
fun pxToSp(px: Float, context: Context): Float {
return px / context.resources.displayMetrics.scaledDensity
}Metode TypedValue.applyDimension — satu-satunya cara yang benar untuk mengonversi sp ke piksel saat runtime. Perkalian langsung dengan scaledDensity kurang dapat diandalkan karena tidak menangani kasus tepi (nilai nol, overflow). scaledDensity berubah saat pengaturan font diubah melalui Settings > Display > Font size.
Android menyediakan lima tingkat skala font yang telah ditentukan: Small (0.85×), Default (1.0×), Large (1.15×), Largest (1.3×) dan tingkat tambahan Very Large (>1.3×) di Android 14+. Produsen perangkat (Samsung, Xiaomi) menambahkan tingkat mereka sendiri — hingga 2.0×. Ukuran minimum teks dalam sp tidak pernah menjamin jumlah piksel tetap.
Di XML sp digunakan secara eksklusif dalam atribut android:textSize. Semua ukuran lainnya — width, height, padding, margin, elevation — diatur dalam dp. Aturannya sederhana: jika elemen menampilkan teks — ukurannya dalam sp, jika elemen menentukan geometri — ukurannya dalam dp.
<!-- Tata letak TextView dengan textSize dalam sp -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
android:textSize="16sp"
android:padding="12dp"
android:lineSpacingExtra="4dp" />
<!-- Menggunakan sumber daya dimens -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/text_body_large" />Disarankan untuk memindahkan ukuran teks ke file dimens.xml. Ini menyederhanakan pemeliharaan tipografi, memungkinkan penggantian ukuran untuk berbagai konfigurasi layar dan memastikan konsistensi di seluruh aplikasi.
<!-- res/values/dimens.xml -->
<resources>
<!-- Material Design Type Scale -->
<dimen name="text_display_large">34sp</dimen>
<dimen name="text_display_medium">28sp</dimen>
<dimen name="text_headline_large">24sp</dimen>
<dimen name="text_headline_medium">20sp</dimen>
<dimen name="text_title_large">18sp</dimen>
<dimen name="text_body_large">16sp</dimen>
<dimen name="text_body_medium">14sp</dimen>
<dimen name="text_label_large">14sp</dimen>
<dimen name="text_label_small">11sp</dimen>
</resources>Material Design Type Scale mencakup 13 tingkat ukuran — dari 11sp untuk label kecil hingga 57sp untuk judul tampilan besar. Proyek Android biasanya menggunakan 8–10 tingkat. Semua nilai harus kelipatan 1sp — nilai pecahan (15.5sp) memperburuk rendering karena posisi subpiksel.
Dalam pengembangan Android modern, teks jarang diatur langsung melalui textSize dalam sp. Sebagai gantinya, sistem MaterialTheme.typography digunakan, di mana setiap gaya telah ditentukan sebelumnya dan mencakup ukuran, berat, jarak antar baris dan letter-spacing.
// Tipografi kustom melalui Typography API
val AppTypography = Typography(
displayLarge = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 34.sp,
lineHeight = 40.sp,
letterSpacing = 0.sp
),
headlineLarge = TextStyle(
fontWeight = FontWeight.SemiBold,
fontSize = 24.sp,
lineHeight = 32.sp
),
titleLarge = TextStyle(
fontWeight = FontWeight.Medium,
fontSize = 18.sp,
lineHeight = 24.sp
),
bodyLarge = TextStyle(
fontWeight = FontWeight.Normal,
fontSize = 16.sp,
lineHeight = 24.sp,
letterSpacing = 0.5.sp
),
labelSmall = TextStyle(
fontWeight = FontWeight.Medium,
fontSize = 11.sp,
lineHeight = 16.sp,
letterSpacing = 0.5.sp
)
)Fungsi ekstensi .sp di Jetpack Compose secara otomatis diterjemahkan ke scale-independent pixels. Saat ukuran font sistem berubah, Compose menghitung ulang fontSize, lineHeight dan spacing sesuai dengan scaledDensity baru. TextUnit (kelas yang mewakili sp) menjamin bahwa teks berskala, sedangkan jarak — tidak.
Di Jetpack Compose sp diwakili oleh tipe TextUnit, yang tidak dapat digunakan secara tidak sengaja untuk ukuran elemen. Kompilator Kotlin memberikan kesalahan jika TextUnit diteruskan ke tempat yang diharapkan Dp. Ini menghilangkan seluruh kelas bug yang terkait dengan penskalaan yang salah.
// TextUnit di Compose — bekerja aman dengan sp
@Composable
fun ArticleCard(title: String, description: String) {
Card(modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Text(
text = title,
style = MaterialTheme.typography.titleLarge
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = description,
style = MaterialTheme.typography.bodyMedium
)
}
}
// Pengaturan fontSize secara eksplisit dalam sp
Text(
text = "Ukuran kustom",
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.primary
)Di Compose tidak ada padanan langsung dari atribut XML android:textSize — ukuran teks diatur melalui TextStyle.fontSize. Sistem MaterialTheme.typography menyediakan gaya yang telah ditentukan yang sesuai dengan Material Design Type Scale. Jika ukuran kustom diperlukan, literal 20.sp digunakan — bahasa menjamin bahwa ini adalah TextUnit, bukan Dp.
Penggunaan sp yang benar — dasar aplikasi Android yang dapat diakses. Di bawah ini dikumpulkan aturan berdasarkan rekomendasi Google Material Design dan Android Developers Guide.
Aturan utama aksesibilitas: pengguna harus dapat memperbesar font tanpa kehilangan fungsionalitas. Jika aplikasi berfungsi dengan benar pada skala font 1.3×, ia akan lulus tes aksesibilitas dasar. Google Play dapat menolak aplikasi jika textSize diatur dalam dp dan antarmuka tidak berskala.
Pertanyaan yang Sering Diajukan
sp (scale-independent pixel) berskala saat ukuran font sistem berubah, sedangkan dp — tidak. sp digunakan hanya untuk teks, dp — untuk semua ukuran elemen lainnya. Faktor konversi: sp = dp × FONT_SCALE.
Tidak. Jarak, tinggi tombol, lebar kartu harus diatur dalam dp. Penggunaan sp untuk jarak menyebabkan elemen tumbuh tidak alami saat font diperbesar dan dapat keluar dari batas layar.
Buka Settings > Display > Font size dan atur nilai maksimum (Largest). Jalankan aplikasi dan periksa bahwa semua teks terbaca, elemen tidak saling tumpang tindih, dan tombol tidak keluar dari batas layar. Untuk otomatisasi, gunakan Espresso dengan UiAutomator.
Material Design merekomendasikan ukuran minimum 11sp untuk labelSmall. Untuk teks utama — dari 14sp (bodyMedium) hingga 16sp (bodyLarge). Ukuran lebih kecil dari 11sp tidak disarankan karena menjadi tidak terbaca di perangkat dengan kerapatan piksel tinggi.
Teks akan ditampilkan dalam ukuran tetap terlepas dari pengaturan font sistem. Pengguna dengan font yang diperbesar tidak akan dapat membaca teks semacam itu dengan nyaman. Ini melanggar persyaratan aksesibilitas WCAG dan dapat menjadi alasan penolakan aplikasi di Google Play.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga