sp — Scale-independent Pixels, een maateenheid voor tekst in Android die rekening houdt met de lettergrootte-instellingen op het apparaat. In tegenstelling tot dp schaalt sp mee met de systeemlettergrootte, wat de toegankelijkheid van interfaces waarborgt. Het artikel legt het verschil uit tussen sp en dp, toont het configureren van textSize in XML en Kotlin en onthult de beste praktijken voor het werken met typografie in Android.
Belangrijkste
sp (scale-independent pixel) — een maateenheid voor lettergrootte in Android die automatisch schaalt volgens de systeeminstellingen van de gebruiker. Wanneer de apparaateigenaar de lettergrootte in de instellingen vergroot, worden alle elementen met sp-waarden proportioneel groter. Dit zorgt voor toegankelijkheid van de interface voor mensen met een slecht gezichtsvermogen.
Basisverhouding: 1 sp = 1 dp bij standaard lettertype-schaal 1.0 (normal). Als de gebruiker het lettertype Large (1.15×) instelt, wordt 16 sp omgezet in 18.4 fysieke pixels. Bij lettergrootte Small (0.85×) worden dezelfde 16 sp 13.6 px. Het schalingsmechanisme wordt beheerd via Settings.System.FONT_SCALE op het niveau van Android Framework.
Volgens Google Material Design Guidelines moet tekst uitsluitend in sp worden ingesteld. Uitzondering — vaste labels in componenten waar grootte cruciaal is voor de lay-out (bijv. tekst in knoppen met vaste hoogte). In dergelijke gevallen wordt aanbevolen dp te gebruiken met handmatige toegankelijkheidscontrole.
Het verschil tussen sp en dp — een van de meest voorkomende onderwerpen bij sollicitatiegesprekken voor Android-ontwikkelaars en in echte code reviews. Beide eenheden zijn gekoppeld aan density-independent pixel (160 dpi = 1 dp = 1 px op mdpi-scherm), maar gedragen zich anders bij verandering van de systeemlettergrootte.
| Kenmerk | sp | dp |
|---|---|---|
| Doel | Tekstgrootte | Afmetingen elementen, afstanden, breedte, hoogte |
| Schalen met lettertype | Ja (scale factor) | Nee |
| Schalen met dichtheid | Ja | Ja |
| API voor instellen | android:textSize | android:layout_width, layout_height, padding, margin |
| Material Design Token | typescale | spacing, sizing |
In de praktijk is het fout om dp voor tekst te gebruiken. Als tekst in dp is ingesteld, schaalt het niet mee bij vergroting van het lettertype, waardoor de interface ontoegankelijk wordt voor gebruikers met een slecht gezichtsvermogen. De omgekeerde fout is het gebruik van sp voor knophoogte of afstanden: bij vergroting van het lettertype kan de knop „opzwellen", waardoor de lay-out wordt verstoord.
Schaling van sp is geïmplementeerd op het niveau van Android Framework in de klasse TypedValue. De omrekeningsformule: sp = dp × scaledDensity, waarbij scaledDensity de schaalfactor is die zowel de schermdichtheid als de lettertype-instelling van de gebruiker in aanmerking neemt.
// Programmatisch verkrijgen van scaledDensity in Kotlin
val scaledDensity = with(context.resources) {
displayMetrics.scaledDensity
}
// sp naar px converteren
fun spToPx(sp: Float, context: Context): Float {
return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP,
sp,
context.resources.displayMetrics
)
}
// px naar sp converteren
fun pxToSp(px: Float, context: Context): Float {
return px / context.resources.displayMetrics.scaledDensity
}De methode TypedValue.applyDimension is de enige correcte manier om sp naar pixels te converteren in runtime. Directe vermenigvuldiging met scaledDensity is minder betrouwbaar omdat het geen edge-cases (nulwaarden, overloop) afhandelt. scaledDensity verandert wanneer de lettertype-instellingen worden gewijzigd via Settings > Display > Font size.
Android biedt vijf vooraf ingestelde niveaus van lettertype-schaal: Small (0.85×), Default (1.0×), Large (1.15×), Largest (1.3×) en een extra niveau Very Large (>1.3×) in Android 14+. Apparaatfabrikanten (Samsung, Xiaomi) voegen eigen niveaus toe — tot 2.0×. De minimale tekstgrootte in sp garandeert nooit een vast aantal pixels.
In XML wordt sp uitsluitend gebruikt in het attribuut android:textSize. Alle andere afmetingen — width, height, padding, margin, elevation — worden ingesteld in dp. De regel is eenvoudig: als een element tekst weergeeft — de grootte in sp, als een element geometrie definieert — de grootte in dp.
<!-- TextView lay-out met textSize in 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" />
<!-- Dimens-bronnen gebruiken -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/text_body_large" />Het wordt aanbevolen tekstgroottes naar het bestand dimens.xml te verplaatsen. Dit vereenvoudigt het onderhoud van typografie, maakt het mogelijk groottes te overschrijven voor verschillende schermconfiguraties en zorgt voor consistentie in de hele app.
<!-- 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 omvat 13 niveaus van groottes — van 11sp voor kleine labels tot 57sp voor grote display-koppen. Android-projecten gebruiken meestal 8–10 niveaus. Alle waarden moeten veelvouden zijn van 1sp — fractionele waarden (15.5sp) verslechteren de weergave vanwege subpixel-positionering.
In moderne Android-ontwikkeling wordt tekst zelden direct via textSize in sp ingesteld. In plaats daarvan wordt het MaterialTheme.typography-systeem gebruikt, waarbij elke stijl vooraf is gedefinieerd en grootte, gewicht, regelafstand en letter-spacing omvat.
// Aangepaste typografie via 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
)
)De extensiefunctie .sp in Jetpack Compose wordt automatisch vertaald naar scale-independent pixels. Bij wijziging van de systeemlettergrootte herberekent Compose fontSize, lineHeight en spacing volgens de nieuwe scaledDensity. TextUnit (de klasse die sp vertegenwoordigt) garandeert dat tekst schaalt en afstanden niet.
In Jetpack Compose wordt sp vertegenwoordigd door het type TextUnit, dat niet per ongeluk kan worden gebruikt voor afmetingen van elementen. De Kotlin-compiler geeft een fout als TextUnit wordt doorgegeven waar Dp wordt verwacht. Dit elimineert een hele klasse bugs die verband houden met onjuiste schaling.
// TextUnit in Compose — veilig werken met 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
)
}
}
// Expliciet instellen van fontSize in sp
Text(
text = "Aangepaste grootte",
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = MaterialTheme.colorScheme.primary
)In Compose is er geen direct equivalent van het XML-attribuut android:textSize — de tekstgrootte wordt ingesteld via TextStyle.fontSize. Het MaterialTheme.typography-systeem biedt vooraf gedefinieerde stijlen die overeenkomen met Material Design Type Scale. Als een aangepaste grootte nodig is, wordt de literal 20.sp gebruikt — de taal garandeert dat dit TextUnit is, niet Dp.
Correct gebruik van sp — de basis van een toegankelijke Android-app. Hieronder staan regels verzameld op basis van aanbevelingen van Google Material Design en Android Developers Guide.
De hoofdregel van toegankelijkheid: de gebruiker moet de mogelijkheid hebben het lettertype te vergroten zonder verlies van functionaliteit. Als de app correct werkt bij een lettertype-schaal van 1.3×, zal deze de basistests voor toegankelijkheid doorstaan. Google Play kan de app afwijzen als textSize in dp is ingesteld en de interface niet schaalt.
Veelgestelde vragen
sp (scale-independent pixel) schaalt mee bij wijziging van de systeemlettergrootte, dp — niet. sp wordt alleen gebruikt voor tekst, dp — voor alle andere afmetingen van elementen. Omrekeningsfactor: sp = dp × FONT_SCALE.
Nee. Afstanden, knophoogte, kaartbreedte moeten worden ingesteld in dp. Gebruik van sp voor afstanden leidt ertoe dat elementen bij vergroting van het lettertype onnatuurlijk groeien en buiten de schermgrenzen kunnen vallen.
Open Settings > Display > Font size en stel de maximale waarde in (Largest). Start de app en controleer of alle tekst leesbaar is, elementen niet overlappen en knoppen niet buiten de schermgrenzen vallen. Gebruik voor automatisering Espresso met UiAutomator.
Material Design beveelt een minimale grootte van 11sp aan voor labelSmall. Voor hoofdtekst — van 14sp (bodyMedium) tot 16sp (bodyLarge). Groottes kleiner dan 11sp worden niet aanbevolen omdat ze onleesbaar worden op apparaten met een hoge pixel dichtheid.
Tekst wordt weergegeven in een vaste grootte ongeacht de systeemlettertype-instellingen. Gebruikers met een vergroot lettertype kunnen dergelijke tekst niet comfortabel lezen. Dit schendt de WCAG-toegankelijkheidseisen en kan leiden tot afwijzing van de app in Google Play.
Samenvatting
We ontwikkelen een mobiele applicatie turnkey
IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.
Lees ook