智慧型應用程式

使用 A2UI 讓代理在 Android 應用程式中生成 UI

喇叭

關於

講座簡介

A2UI 正從以網頁為主的元件轉換為原生 Android。A2UI 0.9 版的新 Jetpack Compose 轉譯器可讓開發人員以原生方式轉譯大型語言模型生成的動態 UI。這項工具不使用網頁檢視,而是採用協同程式驅動的 Actor 架構、密封類別生命週期,以及原生 Material 3 整合。

本課程將逐步介紹新架構,說明伺服器驅動的元件樹狀結構如何轉換為反應式 Compose 節點,以及內建版面配置轉換如何順暢處理結構更新,而不會阻擋 UI。

摘要

  • A2UI 提供宣告式開放 JSON 通訊協定,可讓代理後端描述動態使用者介面,而非文字回覆。
  • 這項通訊協定以目錄為核心,定義允許的元件和函式,以及代表代理控制 UI 部分的介面。
  • Jetpack Compose 的 A2UI 程式庫會使用 Material 3 元件,以原生方式算繪串流介面模型,並內建無障礙功能和漸進式算繪功能。
  • 記憶體內資料模型會立即更新繫結的 UI 元素,不需與代理程式通訊,而傳出事件則會將使用者動作轉送回代理程式。
  • 開發人員可以自訂現有的目錄項目,或建立自訂元件,嚴格控管代理可顯示的內容。

資源

Gemini Notebook

主題

  • a2ui
  • generative-ui
  • jetpack-compose
  • Android
  • ai-agents
  • material-design

轉錄稿

生成式 UI 和 A2UI 簡介

  • 大家好,歡迎參加這場講座。我們將介紹如何使用全新的 A2UI 程式庫,在 Android 應用程式中生成 UI。

  • 我是 Nick Butcher,負責 Jetpack Compose 的產品經理。

  • 大家好,我是 Anton,Compose 團隊的工程師。

  • 我正在開發新的 Jetpack Compose A2UI 轉譯器,很高興今天能與大家分享。

  • 是的,隨著 AI 功能崛起,許多應用程式都在研究如何運用 AI 提升或打造全新的使用者體驗。

  • 生成式 UI 是許多人期待的體驗之一,也就是代理程式後端在執行階段為使用者建立全新 UI,我們認為這非常有趣。

  • 但很可惜,目前許多代理後端的回應都像這樣,夾雜在大量文字中。

  • 舉例來說,我要求代理生成預訂行程的新功能。

  • 提示詞如下:

  • 如您所見,它給出的答案其實相當不錯,但卻被困在這一大段文字中,我無法輕鬆與之互動,而且看起來與我的應用程式其他部分完全不同。

  • 生成式 UI 則可讓您建立類似的體驗,根據動態輸入內容即時生成新的 UI,進而提供更多自訂選項或全新體驗。

  • 以下是使用標準原生元件建立的使用者介面範例。

  • 因此,您現在絕對可以自行建構這類體驗,但必須自行定義與後端交換的格式、事件串流和函式等。

  • A2UI 是 Agent-to-UI 的縮寫,是一種開放通訊協定,採用 JSON 格式定義上述所有內容。

  • 我非常喜歡 A2UI 的其中一個原因,就是它採用宣告式格式。

  • 代理只會傳回要轉譯的 UI JSON 表示法。

  • 它不會傳回用戶端需要執行的任何程式碼,這可能會導致您面臨某些安全漏洞。

  • 只是宣告性質。

  • 那麼,關於 A2UI,我們還需要瞭解哪些概念?

核心概念:目錄和平台

  • 只有兩個主要概念:目錄和平台。

  • 目錄包含文字、按鈕、列和欄等元件,代理可使用這些元件建構 UI。

  • 目錄也提供函式,可讓代理用於設定文字格式、驗證使用者輸入內容或開啟網址。

  • 目錄是一份合約,定義應用程式支援的元件和函式,代理只能使用這些元件和函式建構。

  • 也就是說,正如 Nick 所說,代理不會在應用程式中執行任意程式碼。

  • 它會根據您設計和信任的建構區塊組成 UI。

  • 另一個重要概念是介面。

  • 介面是代理控制的 UI 元素,例如投影片中的行程規劃幫手。

  • 代理會使用 A2UI 通訊協定訊息 (例如 createSurface、updateComponents),以及目錄中定義的元件和函式,以 JSON 格式描述介面的 UI。

  • 說到目錄,目錄是 A2UI 的基本概念,因為它控制代理可用來建構介面的元件。

  • A2UI 規格定義了基本目錄,這是一組可用於建構大多數 UI 的通用元件。

  • Jetpack Compose A2UI 轉譯器會使用 Material 3 元件,提供基本目錄的實作。

  • 大部分的目錄元件都可直接使用。

  • 媒體元件有三種:圖片、影片和音訊播放器,您需要插入所選程式庫。

  • 舉例來說,您可以選擇 Coil 載入圖片,並選擇 Media3 播放影片和音訊。

  • 不過,A2UI 和新版轉譯器程式庫的真正威力,在於您可以建立完全自訂的元件和目錄,並完整控管代理可用來建構 UI 的內容。

  • 我們稍後會再說明目錄。

  • 好的,我們來看看這項功能。

  • 請切換到展示機。

  • 這是我們要使用的示範應用程式,我們將建構 A2UI 轉譯器,向您展示這有多簡單。

  • 如畫面中央的小方塊所示,這是一組可傳送給代理的提示。

  • 因此,如果我們點選其中一個提示,系統會將該提示傳送至實際的服務專員後端,希望示範順利。除了提示之外,我們也會附加一些系統指令。

  • 因此,我們會向後端說明 A2UI 通訊協定和元件目錄 (在本例中,是我們在這裡使用的基本目錄),後端可以使用這些元件來建構 UI,我們也會提供一些建構範例。

  • 在示範應用程式中,對話工作階段實作項目已知道如何從代理的回覆中,擷取原始 JSON A2UI 訊息。

  • 因此,在這個案例中,代理回覆了一些文字,後面接著 A2UI 通訊協定訊息:createSurface、updateComponents。

  • 但目前應用程式只會顯示這個原始 JSON,不會轉譯為 UI。

  • 好的,在我們深入探討並實作程式碼之前,如果可以切換回投影片,只要 1 秒鐘,讓我們退一步,告訴您我們將用來實作這個系統的設計。

  • 喔,有了。

應用程式架構和訊息處理

  • 好,計畫如下。

  • 因此,AI 代理會將回覆串流至應用程式,並由 ChatSession 類別接收。

  • ChatSession 會從代理的回覆中擷取原始 A2UI JSON 訊息,並傳送至 A2UI 訊息處理器。

  • 訊息處理器會設定剖析器,將原始 JSON 訊息轉換為語意表示法。

  • 接著,處理器會根據目錄定義驗證訊息,並將訊息對應至一組介面模型。

  • 介面模型會定義 UI 的外觀,以及代理控制的 UI 部分。

  • 接著,系統會使用程式庫提供的 A2UI 介面可組合項,將這些介面模型算繪為原生 Compose UI。

  • 代理與 UI 之間的通訊是雙向的,因此當使用者與 UI 互動時,使用者動作和錯誤會回傳至代理。

  • 總結來說,主要建構模塊有三個:目錄、訊息處理器和介面。

  • 現在就來編寫程式碼。

  • 好,如果可以切換機器,我們就來建構。

  • 好,第一步是新增依附元件。

  • 如您所見,我們已加入 Material 3 A2UI 依附元件,並同步處理專案,因此不必等待 Gradle 執行。

  • 這是頂層依附元件,定義了使用這些 Material 3 元件的基本目錄實作,但下方還有其他更精細的依附元件。

  • 因此,如果不想使用基本目錄 (稍後會說明原因),可以使用更精細的目錄。

  • 但這會以遞移方式帶入其餘內容。

  • 好的。

  • 我們提過有三個要素。

  • 第一步是定義目錄。

  • 因此,我們要在應用程式中建立工廠函式,協助建構基本目錄的 Material 3 實作例項。

  • 因此,我們在這裡使用這個程式庫函式,即 Material A2UI 基本目錄,這個函式也有版本。

  • 如前所述,這個程式庫提供您需要的所有通用元件,但我們不想強迫您使用特定圖片載入或媒體轉譯程式庫,因此您必須自行提供。

  • 舉例來說,Anton 已經建立這個 Coil AsyncImage 可組合項的包裝函式,我們將使用這個包裝函式載入圖片,以及一些額外的邏輯,讓示範從維基百科查詢圖片。

  • 因此,我們可以輕鬆地將其插入目錄元件中。

  • 同樣地,我們也有類似的轉譯、影片和音訊實作,我們會使用 Media3 程式庫,透過 ExoPlayer 轉譯。

  • 只要像這樣,就能輕鬆插入自己的元件。

  • 目錄接下來需要的是一組標準函式。

  • 因此,這是用戶端可以提供的函式。

  • 同樣地,我們會提供這項功能的實作方式以及基本目錄,但我們需要為其提供情境,您將使用該情境執行特定動作,例如在使用者輕觸項目時開啟 URI。

  • 這樣就完成第一個步驟了。

  • 我們已建立目錄。

  • 接下來,我們必須設定訊息處理器。

  • 因此,這個元件會實際剖析回應等內容。

  • 因此,我們將切換至應用程式的檢視模型,首先,我們將實際例項化先前設定的目錄,因為我們需要該目錄。

  • 接著,我們要建立訊息剖析器和訊息處理器物件,這個物件需要存取目錄,才能根據要使用的元件驗證回應。

  • 我們還需要建立一個元件,也就是剖析器,這個物件負責剖析傳回的 JSON 訊息。

  • 我們在這裡建立 ChatSession 物件。

  • 如前所述,ChatSession 已從代理的回覆中擷取原始 A2UI 訊息。

  • 每當有新的 A2UI 訊息準備就緒時,系統就會呼叫這個 onA2uiMessage 回呼。

  • 因此,我們只需要在每則訊息送達時,將訊息傳遞給處理器即可。

  • 我們呼叫 processInput 函式,並提供剖析器和訊息。

  • 因此,processInput 函式會剖析每則訊息,然後將工作排入佇列,讓處理器根據目錄驗證工作,並更新介面模型。

  • 因此,處理器會將目前的一組有效介面模型公開為 activeSurfaces StateFlow。

  • ChatSession 包含一些邏輯,可將介面模型新增至代理回覆的 UI 狀態,以便轉譯。

  • 因此,我們只需將這個 activeSurfaces StateFlow 做為參數傳遞至 ChatSession。

  • 此外,如前所述,processInput 函式會將工作排入處理器的佇列。

  • 但如要實際開始處理,我們需要在背景執行緒上啟動協同程式。

  • 因此,我們會使用檢視模型範圍,並設定預設調度工具。

  • 在該協同程式中,我們只需要呼叫 processor.collectMessages。

  • 因此,當這個協同程式處於活動狀態時,處理器會處理訊息佇列中的訊息。

  • 因此,我們還需要做一件事:當使用者清除對話記錄時,我們也需要清除目前的介面。

  • 因此,我們呼叫 clearSurfaces。

在 UI 中算繪表面模型

  • 好的。

  • 我們已完成前兩個步驟。

  • 我們建立了目錄,也建立了剖析訊息的處理器。

  • 接下來,我們需要在 UI 中實際算繪這些回覆。

  • 因此,我們會在剖析器剖析這些表面時收集這些表面。

  • 現在,我們會在 UI 中,將這些內容傳遞至這個代理回覆物件,並直接疊代。

  • 接著,我們會使用這個 A2UI 介面可組合函式,並在疊代模型時將每個模型傳遞給它,以便在所需位置算繪內容。

  • 請注意,如果代理選擇顯示大量內容,可能會選擇使用清單等方式。

  • 因此,我們需要為這個元件設定有界高度 (即高度上限),確保元件能正確算繪。

  • 這樣一來,我們就實作了基本的 A2UI 轉譯器。

  • 現在回到應用程式,重新啟動並再次輸入提示詞,代理應該就會使用該指令,

  • 所以我們直接編寫程式碼。

  • 這不是障眼法。

  • 但沒錯,這項功能會使用實際圖片。

  • 它會使用分頁、對話方塊、日期挑選器、滑桿等所有標準 Material 元件,讓您用來建構應用程式,而不只是顯示文字回覆。

  • 由於這是使用實際 Material 元件的實際應用程式,因此您知道,它會執行實際元件執行的操作。

  • 效能與原生應用程式相當。

  • 例如回應深色模式。

  • 這些是 Material 元件。

  • 因此,如果您有自訂顏色、形狀、字體排版等項目的外部 Material Design 主題設定可組合項,這些元件就會採用這些項目,讓外觀與應用程式的其他部分一致。

  • 正如 Nick 所說,這些是原生 Compose 元件,因此具有原生語意。

  • 也就是說,Compose 內建的所有無障礙功能都支援。

  • 因此,TalkBack、字型縮放、鍵盤導覽等功能都能立即使用。

  • 現在,由於您叫用代理在執行階段生成新的 UI,因此可能會有一些延遲。

  • 你可能需要等待服務專員回覆。

  • 程式庫會盡可能縮短這段延遲時間。

  • 因此,如果我們使用這種方法,就會插入一些等待時間,以便更慢地顯示,說明如何盡量減少這種情況。

  • 沒錯,由於代理可能需要一些時間才能串流完整回覆,因此我們會使用漸進式算繪。

  • 因此,只要根元件一到,我們就會開始顯示介面的 UI。

  • 如果子項尚未載入,所有容器元件都會顯示子項的載入預留位置。

  • 子項元件到達時,會使用 Material 3 動作配置進行動畫處理。

  • 好的。

  • 接著切換到下一個提示,展示程式庫的另一項功能。

  • 以下是另一個提示,我們要預訂晚餐座位。

  • 代理選擇使用這個滑桿元件,

  • 如您所見,您可以拖曳並與代理即時建立的使用者介面互動。

  • 請注意,這不只會變更元件上的數字,下方還有這個格式字串,用於計算數字。

  • 這應該不會為了更新,而來回代理,對吧?

  • 這是雙向繫結。

  • 因此,滑桿元件會繫結至這個介面的記憶體內資料模型。

  • 當值變更時,繫結至資料模型中相同路徑的所有元件都會自動更新。

  • 因此,滑桿會讀取要顯示的值,當我拖曳滑桿時,滑桿也會將值寫回模型以進行更新。

  • 因此,所有作業都會在本機執行,不必與代理程式來回通訊。

  • 但我們也可以要求代理更新資料。

  • 所以我們將人數設為 6 人。

  • 請留意代理回覆時的滑桿。

  • 剛剛跳到 6。

  • 來看看代理傳回的內容。

  • 代理不會傳送全新的 UI 說明,而是只傳送一則簡短訊息 updateDataModel,更新滑桿的路徑。

  • 由於滑桿繫結至該路徑,因此會就地更新。

  • 因此,每個介面的資料模型都是以 Compose 快照狀態為基礎建構,而繫結至路徑的每個元件屬性都是衍生狀態。

  • 因此,每當使用者或代理程式更新資料模型中的值時,繫結至相同值的所有元件都會自動重組。

  • 好的。

  • Anton,如果我們想採取行動,按下預訂按鈕,會發生什麼事?

  • 目前不會有任何影響。

  • 按鈕會調度動作,但我們尚未將動作傳送給代理。

  • 我們來解決這個問題。

處理使用者動作和事件流程

  • 好的,就像我們必須連結至處理器來處理輸入內容一樣,我們也需要連結至任何輸出內容,以及使用者在代理建立的 UI 上執行的任何動作。

  • 為此,我們使用處理器公開的 outboundEvents 流程,並收集這項資訊。

  • 因此,您可以根據使用者輕觸動作或對 UI 執行操作,插入任何想要的邏輯。

  • 因此,我們在這裡將所有動作傳回代理,由代理決定要執行的動作,但您也可以在這個階段決定是否要呼叫自己的後端,或前往應用程式中的其他畫面,一切由您決定。

  • Anton 已經在這裡插入這個動作,現在只要點選「確認預訂」動作,系統就會將你執行的動作傳回代理。

  • 在後端,您甚至可以決定叫用某些功能。

  • 我們來看看實際傳送給代理的內容。

  • 這是 A2UI 動作訊息。

  • 其中包含情境,而情境包含一組屬性,是代理程式要求在執行這項動作時傳送的屬性。

  • 因此,當我點選按鈕時,系統會根據資料模型中的目前值,解析該特定屬性,並將其傳送給代理。

  • 好的,到目前為止,代理都相當配合,但我們談論的是 AI,而 AI 可能會出錯。

  • 如果代理在 UI 中犯錯,並將錯誤回報給我們,會發生什麼事?

  • 最後一個提示詞,我們要求代理故意出錯,以便向您示範。

  • 我們來看看會發生什麼事。

  • 是啊

  • 如您所見,其中一個元件標示為錯誤。

  • 現在問題已解決。

  • 這就是代理自我修正迴圈。

  • 在每個元件到達 UI 之前,我們會根據目錄結構定義驗證該訊息。

  • 如果元件與結構定義不符,就會標示為錯誤。

  • 基本目錄實作的轉譯器顯示,錯誤僅限於該特定元件,而其餘 UI 仍會顯示。

  • 在背景中,轉譯器會傳送錯誤訊息給代理,讓代理知道發生什麼問題。

  • 因此,在本例中,我們傳送了一則訊息,指出目錄中找不到不存在的未知元件類型。

  • 接著,代理有機會傳送後續回覆,更新現有 UI,並修正 UI。

  • 是啊

  • 在目前的 Material 基本目錄實作中,我們會立即顯示錯誤,但在自訂元件中,您可以決定在等待代理修正錯誤時,繼續顯示元件的載入指標。

  • 這樣一來,使用者可能完全不會看到錯誤。

建立自訂元件及擴充目錄

  • 說到目錄和自訂元件,目前我們只使用基本目錄,但您當然可以根據自己的需求自訂。

  • 因此,當我們使用工廠函式建立目錄時,所有不同元件都會使用預設值。

  • 因此,您可以視需要輕鬆插入自己的元件。

  • 舉例來說,如果我們在應用程式中有自己的設計系統和按鈕,就可以輕鬆插入。

  • 因此,我們只要在建立目錄執行個體時覆寫這個參數,並建立這個元件定義即可。

  • 因此,如果我們建立新的類別來實作,您會看到這裡有一個介面,即 A2UI 基本目錄類型按鈕。

  • 因此,如果我們實作這個介面,就可以插入自己的元件。

  • 是啊

  • 由於我們要覆寫基本目錄中的元件,因此需要實作這個 A2UI 基本目錄按鈕介面。

  • 因此,這個介面已包含元件的部分資訊,例如名稱、說明和屬性結構定義。

  • 因此,如要實作自己的版本,只要實作這個可組合函式即可。

  • 這個函式需要幾個參數。

  • 因此,這些參數是從代理收到的值,且已通過驗證。

  • 例如子項 ID,這會參照將成為按鈕內容的元件。

  • 此外,這個函式還有一個變體,用於描述按鈕類型、動作定義和其他參數。

  • 在正式環境中導入按鈕時,我們需要使用所有這些參數,但為了示範,我們只需要子項和動作。

  • 現在就來實作這個可組合函式。

  • 在這個可組合函式中,我們要發出自己的自訂讚按鈕類型。

  • 如您所見,我們可以使用 A2UI 提供並驗證的參數。

  • 舉例來說,我們可以在 onClick 函式中調度該動作。

  • 我們可以使用這個程式庫類型 DispatchAction,並將 A2UI 定義的動作傳遞給它。

  • 因此,我們使用自己的按鈕,但仍想轉譯子項內容、標籤或代理程式決定使用的任何內容。

  • 因此,我們使用 observeA2uiComponentState 函式並傳遞 childId,以便取得應轉譯的子項內容。

  • 接著,我們會使用這個 A2uiComponent 可組合函式,並傳遞子元件狀態來算繪。

  • 您可以看到,我們只在子內容載入成功時才算繪,但您也可以在這裡加入自己的邏輯,決定在載入中或錯誤狀態時要顯示什麼內容。

  • 回到示範應用程式中的其中一個範例提示,現在我們使用標準 Material 按鈕取代按鈕。

  • 非常細微,希望你看得出來。

  • 您可以看到我們在這裡也使用了非常自訂的按鈕。

  • 很好,這就是替換程式庫類型的方法。但如果想用自訂類型擴充程式庫,該怎麼做?

  • 只要在目錄中新增內容,就能輕鬆完成這項操作。

  • 因此,Anton 會在這裡建立新類別,實作星級評等元件。

  • 因此,我們要在應用程式中新增一些內容,以便在假設的行程中為餐廳評分。

  • 因此,由於我們並未取代現有元件,所以使用這個更通用的介面,也就是 A2UI 元件介面,您可以看到這個介面有幾個需要覆寫的參數。

  • 前兩個是名稱和說明。

  • 這段程式碼說明瞭元件的內容和功能。

  • 這點非常重要,因為當我們序列化目錄並傳送至後端,告知後端可用來建構 UI 的內容時,代理會使用這項資訊決定是否要在回覆時使用這個元件。

  • 因此,您需要詳細說明,並告訴 AI 您確切知道這項操作的作用。

  • 接下來要覆寫的是 properties 屬性,這個屬性基本上會定義這個元件處理的資料。

  • 因此,我們要建立星級評等列,讓使用者為餐廳評分,並需要兩個屬性。

  • 這會是值,例如使用者選取的星級數量,這會是使用者可以互動及變更的可變動屬性,以及星級數量上限。

  • 因此,我們可以看到 Anton 使用這個動態數字類型屬性做為值。

  • 這樣就能知道實際選取了幾顆星。

  • 這項屬性也有專屬說明,可讓代理瞭解這個值的用途。

  • 接著,我們有一個靜態類型屬性,因此我們只使用這個 A2UI 屬性 (類型為數字),定義這個元件可顯示的星級評等上限。

  • 定義這兩個屬性後,只要傳回即可。

  • 因此,覆寫這個 properties 屬性後,我們會建立清單並傳回。

  • 這樣一來,代理就會知道這個元件的用途。

  • 是啊

  • 正如 Nick 所說,這些屬性定義會做為目錄結構定義的一部分傳送,讓代理瞭解如何使用這個元件。

  • 但這個屬性,相同的屬性定義也用於在執行階段擷取類型值。

  • 因此,只有單一事實來源。

  • 接著來看看如何實作。

  • 首先,假設要存取 max 屬性,由於 max 屬性是靜態屬性,因此代理程式會在 properties 物件中內嵌傳送該屬性的值。

  • 因此,如要存取,我們只需要從屬性物件中取得,方法是使用適當的 max 屬性物件做為索引鍵來參照。

  • 由於這項屬性定義為數字,我們也需要將其轉換為 int 並設定預設值。

  • 接下來是 value 屬性。

  • 由於值屬性是動態屬性,因此會參照資料模型中的某個項目。

  • 因此,如要存取,我們需要使用 properties.bind API,並將屬性物件做為索引鍵做為參數傳遞。

  • 因此,這個方法會傳回資料模型中儲存的這個屬性目前值,並訂閱日後的更新。

  • 因此,每當資料模型更新時,這個元件就會自動重新組成。

  • 同樣地,我們也轉換為 int 並設定一些預設值。

  • 我們還需要設定雙向繫結,才能變更評分。

  • 為此,我們使用 bindUpdater API。

  • 我們傳遞定義屬性的相同屬性物件,因此 bindUpdater 會傳回 lambda,讓我們能變更資料模型中這個屬性的值。

  • 現在可以發出星級評等元件了。

  • 好的。

  • 定義自訂元件後,接著要將其新增至目前使用的目錄。

  • 因此,我們之前只是照原樣使用基本目錄。

  • 現在,我們需要建立新目錄,其中會包含所有基本目錄,並加入自訂元件。

  • 因此,目錄是由三個部分組成。

  • 包含 ID、一組元件和一組函式。

  • 我們會使用 URI 定義 ID,也就是專屬的目錄 ID,以及我們使用的版本。

  • 至於元件,我們會從基本目錄中擷取所有元件,然後使用 add 運算子新增剛才建立的自訂元件。

  • 至於函式,我們只會使用基本目錄中的函式。

  • 這樣一來,我們就擴充了基本目錄,加入新的自訂元件類型。

  • 建立自訂目錄就是這麼簡單。

  • 因此,代理會從我們傳送的系統指令,瞭解如何使用目錄。

  • 現在我們已建立自訂目錄,接著也來更新系統指令。

  • 因此,我們會將目錄物件傳遞至建構系統指令的函式。

  • 現在就來看看吧!

  • 因此,到目前為止,我們都是使用這個標準目錄,傳送基本目錄的靜態結構定義。

  • 現在我們有了自訂目錄,可以使用 toJsonSchemaString 函式動態產生結構定義。

  • 這樣一來,系統就會建立這個目錄的完整 JSON 表示法,包括我們剛才新增的星級評等元件。

  • 系統指示也包含一些範例回覆,供代理參考。

  • 因此,我們也會在這裡變更目錄 ID,讓範例參照正確的目錄。

  • 好的。

  • 這樣一來,我們就擴充了基本目錄,加入自己的自訂類型。

  • 因此,如果我們重新部署並嘗試其中一個提示,應該就能看到評分 UI。

  • 接著代理會回覆。

  • 可以看到,這個星號元件是全新的元件,代理在我們實作之前從未見過。

  • 這不是基本目錄的一部分,而是我們剛建立的。

  • 當我點選星號時,系統會呼叫 bindUpdater lambda,並在資料模型中更新值。

  • 如果提交評分,我們就能查看動作,而動作的背景資訊會包含我們剛才設定的值。

  • 好的,現在請切換回投影片。

  • 我們快速介紹了許多內容,希望您已瞭解如何輕鬆將代理的回覆從文字牆,轉換為實際建立的原生 UI。

重點摘要和資源

  • 希望您覺得整合過程相當簡單。

  • 您需要完成三個主要部分:建立元件目錄、實作剖析邏輯,然後在 UI 中算繪。

  • 希望我們有成功展示,這個程式庫能為您完成許多工作,例如漸進式算繪、驗證結構定義、自我修正迴圈或錯誤處理等。

  • 希望今天的示範能讓您快速瞭解,自訂功能非常簡單。

  • 我們示範了如果您使用 Material,基本目錄如何回應 Material Design 主題設定,但擴充或取代目錄中的元件其實非常簡單。

  • 不過,我認為最有效的方法之一,是實際建立自己的目錄。

  • 如果想盡可能控管代理實際可用的 UI,可以建立完全自訂的元件。

  • 如果想讓它完全自由發揮,可以提供非常基本的元件,例如文字標籤和按鈕,然後說「你來建立 UI」。

  • 如要進一步控管,可以建立更精細的元件,並指定「只能使用這些元件」。

  • 因此,您可以控管代理能執行的操作,以及向使用者顯示的內容。

  • 這就是我們剛推出的新 A2UI 轉譯器程式庫和 Jetpack 程式庫。

    implementation("androidx.compose.material3:material3-a2ui:1.0.0-alpha02")
  • 目前為 Alpha 版,Alpha 02 版最近才推出。

  • 請點選下列連結查看。

  • developer.android.com 網站上提供說明文件和幾個範例。

  • 我們提供一個基本範例,展示基本目錄和更精細的範例,以及我們剛建立的這個 JetPacker 範例應用程式,您將在今天稍後的 ADS 專題演講中再次看到這個應用程式,示範如何建立這些更精細的元件,控制使用者看到的內容。

  • 如前所述,我們目前處於 Alpha 階段,因此現在是試用、提供意見回饋和功能要求的好時機,歡迎告訴我們您想如何使用這項功能,或希望這項功能可以做到哪些事。

  • 歡迎查看程式庫並提供意見。

  • 這就是我們得到的結果。

  • 期待您和代理能運用這項功能,打造出精彩成果。

  • 感謝您!

  • 感謝您!

程式碼

程式碼片段

「重點和資源」中 27:40 的 Kotlin 指令碼片段
implementation("androidx.compose.material3:material3-a2ui:1.0.0-alpha02")