A2UI mimarisinde her yüzey bir bileşen kataloğu tarafından desteklenir. Yapay zeka aracısının kendi kullanıcı arayüzü öğelerini icat etmesi veya rastgele kod oluşturması yerine kataloğunuz, aracıya sunulan bileşenleri, özellik şemalarını ve özellikleri bildirir. Ardından ajan, bu bileşenleri kullanarak bir kullanıcı arayüzü oluşturur.
Uygulamanızın tasarım sistemi için özel bir katalog oluşturduğunuzda, bu katalog tanımlarını somut Jetpack Compose kullanıcı arayüzü öğeleriyle eşleyen bileşenleri uygularsınız. Her A2UI bileşeni (A2uiComponent) kendi özellik şeması sözleşmesini tanımlar, dinamik veriler geldikçe hazır olma durumunu değerlendirir, veri modelindeki reaktif özellikleri bağlar, Compose kullanıcı arayüzünü yayınlar ve kullanıcı etkileşimi işlemlerini tekrar aracıya gönderir.
Compose kullanıcı arayüzü oluşturucu (androidx.a2ui.compose:compose-ui), uygulamanızın tasarım sistemine uygun özel bileşenler uygulamak için gereken arayüzleri ve alıcı kapsamlarını sağlar.
Statik olarak türü belirlenmiş bileşen özellikleri bildirme
Oluşturmadan önce, bir bileşenin aracıdan beklediği özellikleri bildirin. Çalışma zamanı katmanı, hem JSON şema oluşturma hem de çalışma zamanında değerleri çıkarma için kullanılan statik olarak türü belirlenmiş A2uiProperty API'leri sağlar:
// Define static properties, dynamic bindings, and component references
val textProp = A2uiProperty.dynamicString("text", required = true)
val variantProp = A2uiProperty.stringEnum("variant", enumValues = listOf("body", "title"))
val childProp = A2uiProperty.componentId("child", required = true)
val actionProp = A2uiProperty.action("action", required = true)
A2uiComponent arayüzünü uygulama
Bir bileşenin şemasını tanımlamak ve temsilciden alınan özellikleri Compose kullanıcı arayüzüne eşlemek için A2uiComponent arayüzünü uygulayın:
object CustomTextComponent : A2uiComponent {
private val textProp = A2uiProperty.dynamicString("text", required = true)
private val variantProp = A2uiProperty.stringEnum(
"variant",
enumValues = listOf("body", "title"),
)
override val name = "Text"
override val description = "Displays dynamic text."
override val properties = listOf(textProp, variantProp)
@Composable
override fun A2uiComponentScope.isReady(properties: A2uiComponentProperties): Boolean {
// The component does not become ready until dynamic text data arrives
return properties.bind(textProp) != null
}
@Composable
override fun A2uiComponentScope.Content(
properties: A2uiComponentProperties,
modifier: Modifier,
) {
// Reactively resolve dynamic data binding and subscribe to updates
val text = properties.bind(textProp) ?: ""
// Read the static configuration property
val variant = properties[variantProp] ?: "body"
val textStyle = if (variant == "title") {
MaterialTheme.typography.titleLarge
} else {
MaterialTheme.typography.bodyLarge
}
Text(
text = text,
style = textStyle,
modifier = modifier,
)
}
}
Normal ve iki yönlü veri modeli bağlamalarını çözme
Bileşen uygulamaları, dinamik olarak bağlı özellikleri çözmek için A2uiComponentScope kullanır. Normal dinamik özellikler için bind, geçerli değeri döndürür ve veri modeli güncellemelerine otomatik olarak abone olur.
Etkileşimli giriş bileşenleri için bindUpdater, kararlı bir güncelleyici lambda'sı döndürür.
Ajan, yazılabilir bir veri yolu yerine değişmez bir dize sağladıysa güncelleyici lambda null olur. Bu, alanın salt okunur olduğunu gösterir:
val labelProp = A2uiProperty.dynamicString("label", required = true)
val valueProp = A2uiProperty.dynamicBoolean("value")
@Composable
fun A2uiComponentScope.CustomCheckbox(properties: A2uiComponentProperties) {
// Read a dynamic property from the data model subscribing to updates
val label = properties.bind(labelProp) ?: ""
// Bind a property value and its updater to handle two-way data binding
val checked = properties.bind(valueProp) ?: false
val onCheckedChange = properties.bindUpdater(valueProp)
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(
checked = checked,
onCheckedChange = onCheckedChange,
enabled = (onCheckedChange != null), // Read-only if no writable path was bound
)
Text(text = label)
}
}
Kullanıcı işlemlerini aracıya gönderme
Etkileşimli bileşenler, kullanıcı etkinliklerini aracıya geri göndermek için A2uiComponentScope.dispatchAction kullanır:
object CustomButtonComponent : A2uiComponent {
private val childProp = A2uiProperty.componentId("child", required = true)
private val actionProp = A2uiProperty.action("action", required = true)
override val name = "Button"
override val description = "A clickable button."
override val properties = listOf(childProp, actionProp)
@Composable
override fun A2uiComponentScope.Content(
properties: A2uiComponentProperties,
modifier: Modifier,
) {
val actionDefinition = properties[actionProp]
val childId = properties[childProp] ?: return
val currentAction by rememberUpdatedState(actionDefinition)
val onClick: () -> Unit = remember {
{ currentAction?.let { dispatchAction(it) } }
}
Button(onClick = onClick, modifier = modifier) {
val childState = observeA2uiComponentState(id = childId)
when (childState) {
is A2uiComponentState.Loading -> CircularProgressIndicator()
is A2uiComponentState.Error -> Text("Error")
is A2uiComponentState.Success -> A2uiComponent(childState.component)
}
}
}
}
Alt bileşenleri ve aşamalı oluşturmayı işleme
İç içe yerleştirilmiş alt öğeleri destekleyen bileşenler, alt öğe durumlarını gözlemlemek için observeA2uiComponentState(id) kullanır. Bu sayede, üst kapsayıcı kabuğunu oluştururken alt bileşenlerin bağımsız olarak yüklendiği aşamalı oluşturma işlemi yapılabilir:
val headerChildProp = A2uiProperty.componentId("headerId", required = true)
@Composable
fun A2uiComponentScope.CustomCompositeContent(
properties: A2uiComponentProperties,
) {
val headerId = properties[headerChildProp] ?: return
val headerState = observeA2uiComponentState(id = headerId)
when (headerState) {
is A2uiComponentState.Loading -> {
// Render a localized loading placeholder
LinearProgressIndicator()
}
is A2uiComponentState.Error -> {
// Render a localized error fallback
Text("Failed to load header")
}
is A2uiComponentState.Success -> {
// Forward the resolved child component to the visual UI router
A2uiComponent(headerState.component)
}
}
}
Çocuk koleksiyonlarını veya listelerini (ör. sütun, satır ya da listedeki öğeler) işlemek için A2uiProperty.childList kullanarak bir özellik tanımlayın ve bindChildReferences ile alt öğeleri çözümleyin:
val childrenProp = A2uiProperty.childList("children", required = true)
@Composable
fun A2uiComponentScope.CustomColumn(
properties: A2uiComponentProperties,
modifier: Modifier = Modifier,
) {
// Resolve child references (supports both static ID arrays and dynamic data templates)
val childReferences = properties.bindChildReferences(childrenProp) ?: return
Column(modifier = modifier) {
childReferences.forEach { reference ->
key(reference.id, reference.baseDataPath) {
val childState = observeA2uiComponentState(reference)
when (childState) {
is A2uiComponentState.Loading -> CircularProgressIndicator()
is A2uiComponentState.Error -> Text("Failed to load child")
is A2uiComponentState.Success -> A2uiComponent(childState.component)
}
}
}
}
}
Temel Katalog'a yerel medya oluşturma özelliğini entegre edin
Sağlanan Temel Katalog uygulamasını (androidx.compose.material3:material3-a2ui) kullanırken tercih ettiğiniz medya kitaplıklarını (ör. resimler için Coil veya video için ExoPlayer) Temel Katalog'un medya bileşenlerine bağlayabilirsiniz:
// Configure an Image component for the Basic Catalog using Coil
val coilImage = MaterialA2uiBasicCatalogV1Defaults.image { url, desc, scale, modifier, onError ->
AsyncImage(
model = url,
contentDescription = desc,
contentScale = scale,
modifier = modifier,
onError = { state -> onError(state.result.throwable) },
)
}
Uygulama ayrıntıları
Aşağıdaki bölümlerde, yinelemeli kullanıcı arayüzü yayını, dinamik özellik değerlendirmesi ve hata raporlama açıklanmaktadır.
Bileşen uygulaması kullanıcı yolculuklarında aşağıdaki önemli API'ler tanıtılmaktadır:
A2uiComponent: Bileşen meta verilerini, özellik şemalarını, hazırlık kontrollerini (isReady) ve oluşturma yayılımını (Content) tanımlayan arayüz.A2uiProperty: JSON şeması oluşturma ve çalışma zamanı değeri çözümleme için kullanılan statik olarak türü belirlenmiş bir özellik bildirimi.A2uiComponentScope: Bileşen uygulamalarına bağlamla ilgili özellikler (ör. veri bağlama, işlem gönderme ve alt durum gözlemi) sağlayan bir alıcı kapsamı.A2uiComponentProperties: Tür güvenli özellik erişimi sağlayan aracıdan alınan bileşen özellikleri için bir kapsayıcı.A2uiComponentState: Bir bileşenin reaktif yükleme, başarı veya hata çözümü durumunu gösterir.
Yinelemeli kullanıcı arayüzü yayını ve dinamik yönlendirme
Arayan tarafından yükseltilen kök durum (veya bir üst öğe içinde çözümlenen alt bileşen durumu), A2uiComponent composable işlevi aracılığıyla yinelemeli bileşen oluşturmayı başlatır. Bu işlev, çözülen durumu belirli bir kullanıcı arayüzü uygulamasına sıkı bir şekilde bağlamak yerine dinamik bir yönlendirici görevi görür.