sp — Scale-independent Pixels, cihazın yazı tipi boyutu ayarlarını dikkate alan Android'de metin ölçüm birimidir. dp'nin aksine, sp sistem yazı tipi boyutuyla birlikte ölçeklenir ve arayüz erişilebilirliğini sağlar. Bu makale, sp ve dp arasındaki farkı açıklar, XML ve Kotlin'de textSize ayarlamayı gösterir ve Android'de tipografi ile çalışmak için en iyi uygulamaları ortaya koyar.
Önemli Noktalar
sp (scale-independent pixel) — kullanıcının sistem ayarlarına göre otomatik olarak ölçeklenen Android'de yazı tipi boyutu ölçüm birimidir. Cihaz sahibi ayarlardan yazı tipi boyutunu artırdığında, sp değerine sahip tüm öğeler orantılı olarak büyür. Bu, görme engelli kişiler için arayüzün erişilebilirliğini sağlar.
Temel oran: standart yazı tipi ölçeği 1.0 (normal) de 1 sp = 1 dp. Kullanıcı yazı tipini Büyük (1.15×) olarak ayarlarsa, 16 sp, 18.4 fiziksel piksel olur. Küçük yazı tipi boyutunda (0.85×), aynı 16 sp, 13.6 px olur. Ölçeklendirme mekanizması, Android Framework düzeyinde Settings.System.FONT_SCALE aracılığıyla yönetilir.
Google Material Design Yönergelerine göre, metin yalnızca sp cinsinden belirtilmelidir. İstisna, boyutun düzen için kritik olduğu bileşenlerdeki sabit etiketlerdir (örneğin, sabit yükseklikteki düğmelerin içindeki metin). Bu gibi durumlarda, manuel erişilebilirlik kontrolü ile dp kullanılması önerilir.
sp ve dp arasındaki fark, Android geliştirici mülakatlarında ve gerçek kod incelemelerinde en yaygın konulardan biridir. Her iki birim de yoğunluktan bağımsız piksellere (mdpi ekranlarda 160 dpi = 1 dp = 1 px) bağlıdır, ancak sistem yazı tipi boyutu değiştiğinde farklı davranır.
| Özellik | sp | dp |
|---|---|---|
| Amaç | Metin boyutu | Eleman boyutları, dolgu, genişlik, yükseklik |
| Yazı tipi ölçekleme | Evet (ölçek faktörü) | Hayır |
| Yoğunluk ölçekleme | Evet | Evet |
| Ayar API'si | android:textSize | android:layout_width, layout_height, padding, margin |
| Material Design Token | typescale | spacing, sizing |
Pratikte yaygın bir hata, metin için dp kullanmaktır. Metin dp olarak ayarlanırsa, yazı tipi boyutu arttığında ölçeklenmez ve bu da görme güçlüğü çeken kullanıcılar için arayüzü erişilemez hale getirir. Ters hata, düğme yüksekliği veya dolgu için sp kullanmaktır: yazı tipi büyüdüğünde düğme "şişebilir" ve düzeni bozabilir.
sp ölçeklendirmesi, Android Framework düzeyinde TypedValue sınıfında uygulanır. Dönüşüm formülü: sp = dp × scaledDensity, burada scaledDensity hem ekran yoğunluğunu hem de kullanıcının yazı tipi boyutu ayarını dikkate alan bir ölçek faktörüdür.
// Kotlin'de scaledDensity'nin programatik olarak alınması
val scaledDensity = with(context.resources) {
displayMetrics.scaledDensity
}
// sp'den px'e dönüştürme
fun spToPx(sp: Float, context: Context): Float {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP,
sp,
context.resources.displayMetrics
)
}
// px'den sp'ye dönüştürme
fun pxToSp(px: Float, context: Context): Float {
return px / context.resources.displayMetrics.scaledDensity
}TypedValue.applyDimension yöntemi, çalışma zamanında sp'yi piksele dönüştürmenin tek doğru yoludur. scaledDensity ile doğrudan çarpma, uç durumları (sıfır değerler, taşma) ele almadığı için daha az güvenilirdir. scaledDensity, Settings > Display > Font size aracılığıyla yazı tipi ayarları değiştirildiğinde değişir.
Android, beş önceden tanımlanmış yazı tipi ölçeği seviyesi sağlar: Küçük (0.85×), Varsayılan (1.0×), Büyük (1.15×), En Büyük (1.3×) ve Android 14+'te ek bir Çok Büyük (>1.3×) seviyesi. Cihaz üreticileri (Samsung, Xiaomi) kendi seviyelerini ekler — 2.0×'a kadar. sp cinsinden minimum metin boyutu asla sabit piksel sayısını garanti etmez.
XML düzenlerinde, sp yalnızca android:textSize özniteliğinde kullanılır. Diğer tüm boyutlar — genişlik, yükseklik, dolgu, kenar boşluğu, yükseklik — dp olarak ayarlanır. Kural basittir: öğe metin görüntülüyorsa boyutu sp cinsindendir; öğe geometri tanımlıyorsa boyut dp cinsindendir.
<!-- sp ile textSize içeren TextView düzeni -->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
android:textSize="16sp"
android:padding="12dp"
android:lineSpacingExtra="4dp" />
<!-- dimens kaynaklarını kullanma -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/text_body_large" />Metin boyutlarının bir dimens.xml dosyasına çıkarılması önerilir. Bu, tipografi bakımını basitleştirir, farklı ekran yapılandırmaları için boyutların geçersiz kılınmasına izin verir ve uygulama genelinde tutarlılık sağlar.
<!-- 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, 13 boyut seviyesi içerir — küçük etiketler için 11sp'den büyük ekran başlıkları için 57sp'ye kadar. Android projeleri genellikle 8–10 seviye kullanır. Tüm değerler 1sp'nin katları olmalıdır — kesirli değerler (15.5sp), alt piksel konumlandırma nedeniyle işlemeyi bozar.
Modern Android geliştirmede, metin nadiren sp cinsinden textSize aracılığıyla doğrudan ayarlanır. Bunun yerine, her stilin önceden tanımlandığı ve boyut, ağırlık, satır yüksekliği ve harf aralığını içerdiği MaterialTheme.typography sistemi kullanılır.
// Typography API ile özel tipografi
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
)
)Jetpack Compose'daki genişletme işlevi .sp otomatik olarak ölçekten bağımsız piksellere dönüşür. Sistem yazı tipi boyutu değiştiğinde, Compose yeni scaledDensity'ye göre fontSize, lineHeight ve spacing'i yeniden hesaplar. TextUnit (sp'yi temsil eden sınıf), metnin ölçeklenmesini sağlarken dolgunun ölçeklenmemesini garanti eder.
Jetpack Compose'da sp, TextUnit türüyle temsil edilir ve yanlışlıkla eleman boyutları için kullanılamaz. Dp beklendiği yerde TextUnit iletilirse Kotlin derleyicisi hata verecektir. Bu, yanlış ölçeklendirmeyle ilgili tüm bir hata sınıfını ortadan kaldırır.
// Compose'da TextUnit — sp ile güvenli çalışma
@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
)
}
}
// sp cinsinden fontSize'u açıkça ayarlama
Text(
text = "Özel boyut",
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.primary
)Compose'un XML özniteliği android:textSize'in doğrudan bir karşılığı yoktur — metin boyutu TextStyle.fontSize aracılığıyla ayarlanır. MaterialTheme.typography sistemi, Material Design Type Scale'a karşılık gelen önceden tanımlanmış stiller sağlar. Özel bir boyut gerekiyorsa, 20.sp değişmez değeri kullanılır — dil bunun TextUnit olduğunu, Dp olmadığını garanti eder.
sp'nin doğru kullanımı, erişilebilir bir Android uygulamasının temelidir. Aşağıda, Google Material Design ve Android Developers Guide önerilerine dayanan kurallar bulunmaktadır.
Ana erişilebilirlik kuralı: kullanıcı işlevsellik kaybetmeden yazı tipi boyutunu artırabilmelidir. Uygulama 1.3× yazı tipi ölçeğinde doğru çalışıyorsa, temel erişilebilirlik testlerini geçecektir. textSize dp olarak ayarlanmışsa ve arayüz ölçeklenmiyorsa Google Play uygulamayı reddedebilir.
Sıkça Sorulan Sorular
sp (scale-independent pixel) sistem yazı tipi boyutu değiştiğinde ölçeklenirken, dp ölçeklenmez. sp yalnızca metin için kullanılır, dp diğer tüm eleman boyutları için. Dönüşüm faktörü: sp = dp × FONT_SCALE.
Hayır. Dolgu, düğme yüksekliği ve kart genişliği dp olarak ayarlanmalıdır. Dolgu için sp kullanmak, yazı tipi büyüdüğünde öğelerin doğal olmayan şekilde büyümesine ve ekran sınırlarının dışına çıkmasına neden olur.
Settings > Display > Font size'ı açın ve maksimum değere (Largest) ayarlayın. Uygulamayı başlatın ve tüm metnin okunabilir olduğunu, öğelerin çakışmadığını ve düğmelerin ekran sınırlarını aşmadığını kontrol edin. Otomasyon için UiAutomator ile Espresso kullanın.
Material Design, labelSmall için minimum boyut olarak 11sp önerir. Gövde metni için — 14sp (bodyMedium) ila 16sp (bodyLarge). 11sp'den küçük boyutlar önerilmez çünkü yüksek piksel yoğunluklu cihazlarda okunamaz hale gelirler.
Metin, sistem yazı tipi ayarlarından bağımsız olarak sabit boyutta görüntülenecektir. Büyük yazı tipi kullanan kullanıcılar bu metni rahatça okuyamayacaktır. Bu, WCAG erişilebilirlik gereksinimlerini ihlal eder ve uygulamanın Google Play'den reddedilmesine neden olabilir.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun