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

インタラクション ハンドラは、コンポーネントを操作(タップ、ダブルタップなど)できる場所を指定する方法を提供します。インタラクション ハンドラは、デザイン内のすべてのレイヤに追加できます。
ハンドラを追加する
インタラクション ハンドラはどのレイヤにも追加できます。これによりデザイナーは、コンポーネントのどの部分をインタラクティブにするかを指定できます。
hero-item バリアント(フレーム)を選択し、[Parameter] の横にある [+] をクリックします。
tap-handler
を選択して、インタラクション ハンドラを追加します。これによりデベロッパーは、ユーザーによるカードへのタップ操作に反応するコードを記述できます。audio-item バリアントのメニュー アイコンレイヤで前の手順をもう一度行います。これによりデベロッパーは、ユーザーがメニュー アイコンをタップしたときにメニューを表示できます。
[on Menu tapped] ハンドラを選択した場合は、audio-item バリアントにのみ適用されます。他のバリアントにはメニュー アイコンがないためです。一方、[on NewsCard tapped] は 3 つのバリアントすべてに適用されます。3 つのバリアントのいずれかがタップされたときに実行するハンドラを(コード内で)1 つ指定することで、コードとパラメータの重複を削除できます。この仕組みについて詳しくは、以下の Android Studio でコンポーネントを更新するのセクションをご覧ください。
名前付きのバージョンを保存する
このバージョンをコードにインポートする準備ができているとマークしましょう。
Figma ファイルの新しい名前付きバージョンを追加します。[File] > [Save to Version History] に移動し、新しいバージョンのタイトルと説明を入力します(ここでは、任意のタイトルと説明を使用できます)。
タイトルの例: 「追加したインタラクション」
説明の例: 「カードに追加した 2 つのインタラクション ハンドラ」
Android Studio でコンポーネントを更新する
NewsCard コンポーネントを更新しましょう。
Android Studio で [Project] ツール ウィンドウが [Android] ビューになっていることを確認します。次に、
app/ui-packages/news_card/
を右クリックし、コンテキスト メニューの下部にある [Update UI Package] をクリックします。をクリックして、プロジェクトをビルドします。これにより、更新された UI パッケージが取得され、コンポーズ可能なコードの更新バージョンが生成されます。
app/java/com/example/hellonews/newscard/NewsCard.kt
を見ると、インタラクション ハンドラが NewsCard(onNewsCardTapped
、onMenuTapped
)にパラメータとして追加されていることがわかります。// 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 ) { ...
アプリに統合する
それでは、インタラクションにハンドラを追加しましょう。
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(...) ...
postTop
には、onNewsCardTapped
とonMenuTapped
のハンドラを追加します。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)) ... } }
投稿ごとに
onNewsCardTapped
とonMenuTapped
のハンドラを追加します。@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)) } } }
引き続き
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(...) ...
投稿ごとに
onNewsCardTapped
とonMenuTapped
のハンドラを追加します。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)) } } }
▶ をクリックしてアプリをビルドし、エミュレータで実行します。
今回は、Relay の高度な機能について学習しました。
Relay の操作方法について詳しくは、Relay のワークフローのセクションをご覧ください。また、フィードバックがございましたら、ぜひお寄せください。