3.1 KiB
Native range-display truncation evidence
Reported symptom
On the target 1920x1080 television, a batch that called tickets 00010 and 00011 rendered the main current-call field as only 00010 至; the latest-ticket metric at the right still showed 00011.
Boundary verification
The production public snapshot was read on 2026-08-12 from GET https://queue.nianxx.cn/api/display/YYHHC/snapshot. It contained:
latest_ticket_number: "00011"current_batch.ticket_count: 2current_batch.tickets[0].display_number: "00010"current_batch.tickets[1].display_number: "00011"
DisplayFormatting.currentBatchNumbers therefore produces the complete string 00010 至 00011. This rules out the server response, JSON parser, and range formatter as the cause.
Root cause
The original native current-number TextView started at 74sp, allowed one line, and called NativeDisplayUi.autoSize. That helper only activated Android platform auto-size on API 26 and later, although the APK supports API 23. On API 23-25, long range text stayed at 74sp and could be silently clipped by the half-width current-call panel. Platform behavior and display density also made the guarantee device-dependent on newer releases.
An API-25 Robolectric regression using a full ProjectDisplayView, 1920x1080 exact layout, and the real two-ticket snapshot was run before the fix. Its red signal confirmed the legacy view retained the initial 74sp rather than applying a fitting policy.
Fix and invariant
SingleLineFitTextView now owns current-call fitting on API 23 and later. On text, size, or padding changes it:
- computes actual content width and height after compound padding;
- measures the real text and font metrics with a copy of the active
TextPaint; - binary-searches for the largest whole-sp size that fits both dimensions;
- enforces a single line and never ellipsizes;
- falls below the normal 30sp readability floor only when necessary to preserve the complete ticket range.
Short single numbers still receive the largest fitting size, up to 74sp.
Verification
gradlew.bat clean testDebugUnitTest lintDebug assembleDebug: PASS.- JVM tests: 56 across 12 suites, 0 failures, 0 errors, 0 skipped.
- Lint: 0 errors, 24 warnings.
ProjectDisplayViewTestlocks the full00010 至 00011string, one-line behavior, and no ellipsis on API 25.- A narrow ASCII control asserts the fitted
TextPaintwidth and font height are within actual content bounds; deterministic sizing tests call the production two-stage decision and lock largest-fitting selection, full-size selection, below-floor fallback, and the 1sp terminal boundary. - APK: versionCode 9, versionName 1.5.2; Android Debug v1/v2 signatures verified.
- Build and deliverable SHA-256:
0D56C10B8CE706893F3EA8E59B21329847517F56F7347ABEA127AB30C6C71D77.
Remaining acceptance
Robolectric's host font metrics are not the target television's font metrics. The production code uses the device's real TextPaint, but final acceptance still requires installing 1.5.2 on the target television and visually confirming both endpoints for 00010 至 00011 and at least one wider representative range.