インタラクション ハンドラをデザインに追加する

このセクションでは、インタラクション ハンドラを介してデザインにインタラクションを追加する方法について説明します。

タップ インタラクションのある NewsApp

インタラクション ハンドラは、コンポーネントを操作(タップ、ダブルタップなど)できる場所を指定する方法を提供します。インタラクション ハンドラは、デザイン内のすべてのレイヤに追加できます。

ハンドラを追加する

インタラクション ハンドラはどのレイヤにも追加できます。これによりデザイナーは、コンポーネントのどの部分をインタラクティブにするかを指定できます。

  1. hero-item バリアント(フレーム)を選択し、[Parameter] の横にある [+] をクリックします。tap-handler を選択して、インタラクション ハンドラを追加します。これによりデベロッパーは、ユーザーによるカードへのタップ操作に反応するコードを記述できます。

    hero-item バリアントが選択された Figma プラグイン
  2. audio-item バリアントのメニュー アイコンレイヤで前の手順をもう一度行います。これによりデベロッパーは、ユーザーがメニュー アイコンをタップしたときにメニューを表示できます。

    メニュー アイコン バリアントが選択された Figma プラグイン
  3. [on Menu tapped] ハンドラを選択した場合は、audio-item バリアントにのみ適用されます。他のバリアントにはメニュー アイコンがないためです。一方、[on NewsCard tapped] は 3 つのバリアントすべてに適用されます。3 つのバリアントのいずれかがタップされたときに実行するハンドラを(コード内で)1 つ指定することで、コードとパラメータの重複を削除できます。この仕組みについて詳しくは、以下の Android Studio でコンポーネントを更新するのセクションをご覧ください。

    タップハンドラが選択された Figma プラグイン

名前付きのバージョンを保存する

このバージョンをコードにインポートする準備ができているとマークしましょう。

  1. Figma ファイルの新しい名前付きバージョンを追加します。[File] > [Save to Version History] に移動し、新しいバージョンのタイトルと説明を入力します(ここでは、任意のタイトルと説明を使用できます)。

    タイトルの例: 「追加したインタラクション」

    説明の例: 「カードに追加した 2 つのインタラクション ハンドラ」

    メニューの [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 を見ると、インタラクション ハンドラが NewsCardonNewsCardTappedonMenuTapped)にパラメータとして追加されていることがわかります。

    // 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. 投稿ごとに 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. 投稿ごとに onNewsCardTappedonMenuTapped のハンドラを追加します。Audio バリアントにはメニューがあるため、createOnTappedonMenuTapped に割り当てます。

    @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 のワークフローのセクションをご覧ください。また、フィードバックがございましたら、ぜひお寄せください。