Learning outcome
Understand the contract between allowed JSON components and Compose.
A catalog defines the vocabulary the producer may use and the native implementations that render it. The sample uses the official Material basic catalog but restricts server output to Text, Column, Row, Card, Button, CheckBox, Divider and one bundled Image. The full library supports more than this sample exposes. Adding a component name to a prompt alone does not implement or authorize it.
Pinned catalog configuration excerpt
fun communityCatalog(): A2uiCatalog =
materialA2uiBasicCatalogV1(
image = MaterialA2uiBasicCatalogV1Defaults.image {
url, description, _, modifier, onError ->
if (url == "asset://community")
Image(
painterResource(R.drawable.community_art),
description,
modifier.fillMaxWidth().height(160.dp)
.clip(RoundedCornerShape(16.dp)),
contentScale = ContentScale.Crop,
)
else Text("Image unavailable", modifier)
},
// Video/audio implementations are supplied in the source.
// This excerpt omits those arguments; it is not a drop-in function.
urlOpener = { _ -> error("Use a validated event action to open links") },
messageFormatter = { pattern, _, _ -> pattern },
localeProvider = A2uiLocaleProvider.Default,
)
Read the complete CommunityCatalog.kt rather than pasting the abbreviated function. The image renderer deliberately recognizes only asset://community. The picture is an illustration, not a venue photograph. The URL opener does not accept arbitrary generated navigation. The app handles event links after resolving a known event ID.
CommunityScreen owns the header, text field, setup dialog, error card and inspector. A2uiSurface owns the generated response region. This distinction gives the agent room to select structure while keeping trusted navigation and setup predictable. MaterialTheme and the image implementation control styling; the model does not send arbitrary Compose source.
Locate the production rendering boundary
rg -n 'A2uiSurface|activeSurfaces|collectAsStateWithLifecycle' app/src/main/java
rg -n 'materialA2uiBasicCatalogV1|urlOpener' app/src/main/java
A valid component tree may still overflow, put too many buttons in one row or provide unclear labels. Treat prompt guidance as a preference, not a layout guarantee. Test narrow widths, larger fonts, long event names, TalkBack order and descriptive image text. Do not claim an accessibility audit from successful compilation.
Practice and checkpoint
Identify two changes that require app code and two that Gemini can choose within the existing contract. Expected: a new native media renderer and local styling require app code; a different heading and a permitted Card/Column composition can come from the model. Inspect a generated screen at large font size and record one UX risk.
Source and next steps
- Pinned implementation — The exact app and server revision used by this lesson.
Back to roadmap · Practice this unit in the codelab