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

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

設有輕觸互動的 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 Relay 外掛程式 (如果尚未開啟)。

  2. 按一下對話方塊右下角的 [與開發人員共用]。

  3. 在「與開發人員畫面共用」中,輸入版本的名稱和說明。

    標題範例:新增互動

    說明範例:在資訊卡中新增兩個互動處理常式

  4. 按一下「儲存」

  5. 在 MAC 上按下 CMD-L 鍵,在 Windows 上按下 CTRL-L 鍵,將元件連結複製到剪貼簿。

在 Android Studio 中更新元件

現在讓我們更新 NewsCard 元件:

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

    在內容選單中更新 UI 套件選項
  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(
      modifier: Modifier = Modifier,
      view: View = View.HeroItem,
      thumbnail: Painter = EmptyPainter(),
      headline: String = "",
      author: String = "",
      date: String = "",
      onNewsCardTapped: () -> Unit = {},
      onMenuTapped: () -> Unit = {}
    ) {
    ...
    

整合至應用程式

現在,讓我們將一些處理常式新增至互動。

  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,為 onNewsCardTapped 新增處理常式。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),
              view = View.HeroItem
          )
          Spacer(modifier = Modifier.size(12.dp))
          ...
      }
    }
    
  3. 針對每個 post,為 onNewsCardTapped 新增處理常式。

    @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),
                  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,為 onNewsCardTapped 新增處理常式。由於 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. 按一下 ▶ 即可建構應用程式,並在模擬器中執行。

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

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

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