Android 字體放大如何令按鈕變得無法觸及
When larger text puts a button out of reach on Android
Samya 以 Jetpack Compose 範例展示,放大字體可令固定高度的自訂操作元件截斷標籤;內容區不可捲動時,按鈕亦可能移出畫面。修正版改用垂直捲動容器、最小高度及按內容調整的內距,讓文字可按需要換行。在 Android 16 / API 36 模擬器(約 309 × 686 dp)測試時,字體縮放設為 2.0 的原版按鈕無法觸及;這只反映該配置,不能推及所有裝置或應用。
Someone opens a library app to collect a book. They make the text on their phone larger, read the collection details and try to confirm. The label is cut off. On a compact screen, the confirmation button has disappeared below the visible area—and an upward swipe doesn't bring it back.
This is an illustrative example, built to make a layout problem visible. The app screens in our video are real captures from a small Jetpack Compose sample; the surrounding scenes are illustrated. The sample deliberately constrains the layout. It is not a customer app or a claim that larger text breaks every app.
The short video shows the problem and the corrected flow:
The text grew. The layout didn't make room.
In the broken version, we used a custom action with a fixed height and clipped its contents. At a larger font size, the text needed more vertical space than the action allowed. The content area also did not scroll, so the action could move below the viewport with no way to reach it.
Those are two separate problems. A label can be clipped even when its button is on screen. A perfectly readable button can still be unreachable when the page cannot scroll.
Here's the shape of the constrained custom action in the sample, simplified to focus on the constraint:
Box(
modifier = Modifier
.fillMaxWidth()
.height(30.dp)
.clipToBounds()
) {
Text(
text = "Confirm collection",
fontSize = 20.sp,
modifier = Modifier
.padding(start = 16.dp, top = 6.dp)
.wrapContentHeight(unbounded = true, align = Alignment.Top)
)
}
This is deliberately restrictive custom UI, not standard Material Button behavior. A fixed height alone does not prove that every button will clip: padding, font metrics, constraints, width and text all affect the result.
Give the content room and a way to scroll
In the corrected sample, the content sits in a vertically scrollable container. The action has a minimum height instead of the broken fixed height, with content-driven padding. Its text can wrap as needed.
The relevant shape looks like this:
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(24.dp)
) {
// Book and collection details
Box(
modifier = Modifier
.fillMaxWidth()
.heightIn(min = 56.dp)
.clickable { /* confirm the collection */ }
.padding(16.dp),
contentAlignment = Alignment.Center
) {
Text("Confirm collection", fontSize = 20.sp)
}
}
This is a simplified illustration of the layout choices, not a drop-in replacement for every screen. A production action should also have appropriate semantics, a clear role and accessible interaction behavior; a Material button may be a better starting point than a custom clickable Box. Check the surrounding constraints too: changing only the button's minimum height will not fix a parent that clips its children or prevents scrolling. Compose's scroll modifier guidance explains how to make content larger than its available space scrollable.
What we actually tested
We tested the sample on an Android 16 / API 36 emulator in portrait, using a compact configuration of approximately 309 × 686 dp. With the system font scale at 2.0, the broken, non-scrolling layout left the action outside the visible content area. An upward swipe did not change the content. In the corrected version, we scrolled to the action, tapped it and observed the “Reserved” state.
At a 1.6 font scale, the broken custom action also clipped part of its label. The clipping in the capture is subtle: roughly 13% of the glyph height compared with an uncut reference.
This is one emulator configuration, not an accessibility certification or proof of behavior on every device. In an earlier, taller configuration, the action remained reachable. Screen size, density, language, content and font settings can all change the result.
Test the task, not just the first screen
Android 14 introduced non-linear font scaling up to 200%. Larger text sizes do not necessarily scale at the same rate as smaller ones. Android recommends using sp for text and testing at the maximum setting; see Android's font-scaling guidance.
For a practical check:
- Set the system font size to its maximum on a test device or emulator. Also try a smaller screen or split-screen window where appropriate.
- Open a real flow in your app and complete it. Can you read each label, scroll to the next step and reach the action?
- Check long or translated text, error messages and dynamic content. Look for clipping, overlaps and actions hidden by fixed regions.
- Repeat at your usual text size too. A change that helps at one size should not make the ordinary flow harder to use.
The aim isn't to make every screen look identical at every setting. It's to make sure the person using the app can still understand it and finish what they came to do.
Disclosure: This article was drafted with AI assistance.
來源:DEV Community · dev.to