Flutter 3.10 liveRegion: should CustomPaint updates rely on manual Semantics wrapping?
0 reputation · 24 Jul 2020, 21:27 UTC
0 reputation · 24 Jul 2020, 21:27 UTC
Flutter 3.10 added the liveRegion property to SemanticsConfiguration, letting developers mark dynamic content so screen readers announce changes. I am building a dashboard where a CustomPaint canvas redraws values continuously, and I want those updates announced politely without flooding the accessibility tree.
The uncertainty is the documented compatibility boundary: semantics upgrades are only guaranteed for widgets inheriting from RenderObjectWidget, while CustomPaint uses RenderCustomPaint. That leaves it unclear whether wrapping the painter in a Semantics widget with liveRegion set is a supported, stable pattern or an undocumented workaround that could regress on a future minor release. Community packages seem split between manual annotation and hoping for a built-in painter-level mixin.
Does Flutter officially support applying Semantics with liveRegion around a CustomPaint, and is that behavior guaranteed across upgrades? Is there a recommended pattern for throttling announcements from a frequently repainting canvas? Should I wait for a painter-level API, or is manual annotation the intended long-term approach?
35275 reputation · 25 Jul 2020, 01:03 UTC
Yes – wrapping a CustomPaint in a Semantics widget with liveRegion: true is a supported, documented pattern in Flutter 3.10 and is expected to remain stable unless the framework explicitly changes how RenderCustomPaint participates in the semantics tree.
CustomPaint is a RenderObjectWidget; its render object (RenderCustomPaint) is inserted into the semantics tree like any other render object.liveRegion: true on a Semantics widget causes the framework to announce changes only when the semantics node itself changes (via markNeedsSemanticsUpdate or a rebuild with different properties).liveRegion API exists yet; the manual wrapper is the current recommended approach.The semantics system treats the Semantics widget as a container node. When its properties change, the node is marked dirty and the accessibility service receives an update. Because CustomPaint does not expose its own semantics properties, the wrapper is the only place to attach liveRegion. Repainting the canvas does not automatically trigger semantics updates unless the wrapper’s configuration changes, which is why you can throttle announcements by controlling when the wrapper rebuilds.
CustomPaint with a Semantics widget that sets liveRegion: true and, if the painted area should be announced as a single unit, container: true.RepaintBoundary around the CustomPaint to isolate canvas repaints from the rest of the widget tree.setState that changes the painted values (e.g., 200 ms) or only call setState when the value crosses a meaningful threshold.Do you need the entire painted area to be treated as a single accessibility node? If yes, keep container: true; if you want each logical sub‑element (e.g., separate gauges) to be announced individually, you would need to split the painting into multiple CustomPaint instances or provide custom semantics via Semantics children. This detail determines whether the simple wrapper is sufficient or if a more granular approach is required.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.