在設計中新增互動處理常式

在這一部分中,我們將學習如何運用互動處理常式在設計中新增互動。

設有輕觸互動的 NewsApp

互動處理常式可讓您指定元件可提供互動 (輕觸、輕觸兩下等等) 的位置。互動處理常式可新增至設計的任何層。

新增處理常式

互動處理常式可新增至任何層。這樣一來,設計人員就能指定元件的哪些部分具有互動性。

  1. 選取「hero-item」子類 (指框架),按一下「Parameter」旁邊的「+」,然後選取 tap-handler 即可新增互動處理常式。這樣開發人員就能編寫程式碼,以便回應使用者輕觸資訊卡的動作。

    已選取 hero-item 子類的 Figma 外掛程式
  2. 針對「audio-item」子類中的「menu」圖示層,重複上一個步驟。這可讓開發人員在使用者輕觸選單圖示時顯示選單。

    已選取 menu 圖示子類的 Figma 外掛程式
  3. 如果您選取「on Menu tapped」處理常式,會發現這個選項僅適用於「audio-item」子類,原因是其他子類沒有選單圖示。但是,「on NewsCard tapped」適用於所有三個子類。這表示您可以在程式碼中提供一個處理常式,以便在使用者輕觸這三個子類中的任一個時執行,藉此排除程式碼和參數的重複情況。如要進一步瞭解運作方式,請參閱下方的「在 Android Studio 中更新元件」一節。

    已選取輕觸處理常式的 Figma 外掛程式

儲存已命名版本

現在,讓我們將這個版本標示為準備就緒,以便匯入程式碼中。

  1. 新增 Figma 檔案的已命名版本。依序前往「File」>「Save to Version History」,然後輸入新版本的標題和說明 (這裡的任何標題和說明皆為有效)。

    標題範例:「Added Interactions」

    說明範例:「Two interaction handlers added to cards」

    選單中的「Save to version history」選項

在 Android Studio 中更新元件

現在讓我們更新 NewsCard 元件:

  1. 在 Android Studio 中,確認「Project」工具視窗位於「Android」檢視畫面中。接著,在 app/ui-packages/news_card/ 上按一下滑鼠右鍵,然後點選靠近內容選單底部的「Update UI Package」

    內容選單中的「Update UI Package」選項
  2. 按一下 「Make Project」按鈕 圖示來建構專案。這項操作會採用更新後的 UI 套件,並產生可組合程式碼的更新版本。

    工具列中的建構按鈕
  3. 查看 app/java/com/example/hellonews/newscard/NewsCard.kt 時,您會發現互動處理常式是以參數形式新增至 NewsCard (onNewsCardTappedonMenuTapped)。

    // Design to select for NewsCard
    enum class View {
        HeroItem, ArticleItem, AudioItem
    }
    
    /**
    * Displays a summary of a news article.
    *
    * This composable was generated from the UI package 'news_card'.
    * Generated code; do not edit directly
    */
    @Composable
    fun NewsCard(
        onNewsCardTapped: () -> Unit = {},
        thumbnail: Painter,
        headline: String,
        author: String,
        date: String,
        onMenuTapped: () -> Unit = {},
        modifier: Modifier = Modifier,
        view: View = View.HeroItem
    ) {
    ...
    

整合至應用程式

現在,讓我們在互動中加入一些處理常式。

  1. app/java/com/example/hellonews/ui/home/HomeScreen.kt 中,向下捲動至第 175 行附近的 PostListArticleStories

    ...
    @Composable
    fun HomeScreen(...)
    
    @Composable
    private fun PostList(...)
    
    @Composable
    private fun PostListArticleStoriesSection(...)
    
    @Composable
    private fun SearchArticlesSection(...)
    
    @Composable
    private fun PostListArticleStories(
        postTop: Post,
        posts: List<Post>,
        createOnTapped: (String, String) -> () -> Unit
    ) {...}
    
    @Composable
    private fun AudioStoriesTitle(...)
    
    @Composable
    private fun PostListAudioStories(...)
    
    @Composable
    fun Dialog(...)
    ...
    
  2. 針對 postTop,為 onNewsCardTappedonMenuTapped 新增處理常式。createOnTapped 會開啟對話方塊,並把參數做為其中的標題和內文。

    @Composable
    private fun PostListArticleStories(
        postTop: Post,
        posts: List<Post>,
        createOnTapped: (String, String) -> () -> Unit
    ) {
        ...
        Column(
            horizontalAlignment = Alignment.Start,
            modifier = ...
        ) {
            Spacer(modifier = Modifier.size(12.dp))
            NewsCard(
                thumbnail = painterResource(postTop.imageId),
                headline = postTop.title,
                author = postTop.metadata.author.name,
                date = postTop.metadata.date,
                onNewsCardTapped = createOnTapped("Card Tapped", postTop.title),
                onMenuTapped = {},
                view = View.HeroItem
            )
            Spacer(modifier = Modifier.size(12.dp))
            ...
        }
    }
    
  3. 針對每個 post,為 onNewsCardTappedonMenuTapped 新增處理常式。

    @Composable
    private fun PostListArticleStories(
        postTop: Post,
        posts: List<Post>,
        createOnTapped: (String, String) -> () -> Unit
    ) {
        ...
        Column(
            horizontalAlignment = Alignment.Start,
            modifier = ...
        ) {
            ...
    
            posts.forEach { post ->
                NewsCard(
                    thumbnail = painterResource(post.imageId),
                    headline = post.title,
                    author = post.metadata.author.name,
                    date = post.metadata.date,
                    onNewsCardTapped = createOnTapped("Card Tapped", post.title),
                    onMenuTapped = {},
                    view = View.ArticleItem
                )
                Spacer(modifier = Modifier.size(12.dp))
            }
        }
    }
    
  4. 一樣是在 HomeScreen.kt 中,繼續向下捲動至第 260 行附近的 PostListAudioStories

    ...
    @Composable
    fun HomeScreen(...)
    
    @Composable
    private fun PostList(...)
    
    @Composable
    private fun PostListArticleStoriesSection(...)
    
    @Composable
    private fun SearchArticlesSection(...)
    
    @Composable
    private fun PostListArticleStories(...)
    
    @Composable
    private fun AudioStoriesTitle(...)
    
    @Composable
    private fun PostListAudioStories(
        posts: List<Post>,
        createOnTapped: (String, String) -> () -> Unit
    ) {...}
    
    @Composable
    fun Dialog(...)
    ...
    
  5. 針對每個 post,為 onNewsCardTappedonMenuTapped 新增處理常式。由於 Audio 子類確實有選單,因此我們也將 createOnTapped 指派給 onMenuTapped

    @Composable
    private fun PostListAudioStories(
        posts: List<Post>,
        createOnTapped: (String, String) -> () -> Unit
    ) {
        Column(
            horizontalAlignment = ...,
            modifier = ...
        ) {
            posts.forEach { post ->
                NewsCard(
                    thumbnail = painterResource(post.imageId),
                    headline = post.title,
                    author = post.metadata.author.name,
                    date = post.metadata.date,
                    onNewsCardTapped = createOnTapped("Card Tapped", post.title),
                    onMenuTapped = createOnTapped("Menu Tapped", post.title),
                    view = View.AudioItem
                )
                Spacer(modifier = Modifier.size(12.dp))
            }
        }
    }
    
  6. 按一下 ▶ 即可建構應用程式,並在模擬器中執行。

    工具列中的執行按鈕
    預覽中的新聞應用程式實際運作情形

    太棒了!您已瞭解 Relay 的進階功能。

如要進一步瞭解如何使用 Relay,請參閱「Relay 工作流程」部分。如有任何意見回饋,也歡迎與我們分享。