Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How does the Relay connect Android app development and Design?

How does the Relay connect Android app development and Design?

At Google I/O 2023, there will be one session on Relay, which is an experience of the process of developing a single Android application using Relay. This deck introduces how to connect Android app development and design using Relay.

- Build a complete app with Relay and Compose
- https://io.google/2023/program/bac078a1-4c65-4566-b200-71e8cbe14601/
- Codelab: Build a complete app with Relay and Jetpack Compose
- https://codelabs.developers.google.com/relay-complete-app#0
- Overview: Relay
- https://developer.android.com/jetpack/compose/tooling/relay

Ryosuke Horie

June 01, 2023
Tweet

More Decks by Ryosuke Horie

Other Decks in Programming

Transcript

  1. How does the Relay connect Android
    app development and Design?

    ZOZO, Inc.

    Technology Division Technology Strategy Department CTO Section

    Ryosuke Horie
    Copyright © ZOZO, Inc.
    1
    2023/6/1 

    Recap: Google I/O 2023


    View Slide

  2. © ZOZO, Inc.
    ZOZO, Inc.

    Technology Division 

    Technology Strategy Department

    CTO Section

    Ryosuke Horie

    2

    View Slide

  3. © ZOZO, Inc.
    3
    https://io.google/2023/program/bac078a1-4c65-4566-b200-71e8cbe14601/

    View Slide

  4. © ZOZO, Inc.
    4
    What is Relay?

    ● Figma to Composables


    View Slide

  5. © ZOZO, Inc.
    5
    What is Relay?

    ● Easy to build apps with Figma's UI components


    View Slide

  6. © ZOZO, Inc.
    6
    Relay workflow

    Figma
    Components

    View Slide

  7. © ZOZO, Inc.
    7
    Relay workflow

    Figma
    Relay for Figma Plugin
    Components

    View Slide

  8. © ZOZO, Inc.
    8
    Create UI Packages from Component with Relay Plugin


    View Slide

  9. © ZOZO, Inc.
    9
    What is UI Packages?

    ● Intermediate representation of UI shared between Figma and Android
    Studio

    https://developer.android.com/jetpack/compose/tooling/relay/create-ui-packages

    View Slide

  10. © ZOZO, Inc.
    10
    What is UI Packages?

    ● Intermediate representation of UI shared between Figma and Android
    Studio

    ● The UI package contains the following information:

    ○ Layout Information

    ○ UI Package Summary

    ○ Content and interaction parameters

    ○ Styling information

    ○ Font and image assets

    https://developer.android.com/jetpack/compose/tooling/relay/create-ui-packages

    View Slide

  11. © ZOZO, Inc.
    11
    Relay workflow

    Figma
    Relay for Figma Plugin UI Packages
    Components

    View Slide

  12. © ZOZO, Inc.
    12
    Relay workflow

    Figma
    Relay for Figma Plugin UI Packages
    Android Studio
    Relay for Android Studio Plugin
    Components
    Android Studio icon from: https://developer.android.com/studio

    View Slide

  13. © ZOZO, Inc.
    ● UI Package is fetched by entering the Figma source URL

    13
    Import UI Package with Relay for Android Studio Plugin



    View Slide

  14. © ZOZO, Inc.
    ● UI Package is fetched by entering the Figma source URL

    ● Fetched UI Packages are placed under ui-packages

    14
    Import UI Package with Relay for Android Studio Plugin



    View Slide

  15. © ZOZO, Inc.
    15
    Relay workflow

    Figma
    Relay for Figma Plugin UI Packages
    Android Studio
    Relay for Android Studio Plugin
    Components
    Android Studio icon from: https://developer.android.com/studio

    View Slide

  16. © ZOZO, Inc.
    16
    Relay workflow

    Figma
    Relay for Figma Plugin UI Packages
    Android Studio
    Relay for Android Studio Plugin
    Components
    Relay Gradle Plugin
    Android Studio icon from: https://developer.android.com/studio

    View Slide

  17. © ZOZO, Inc.
    17
    Generate code from UI package with Relay Gradle Plugin





    ● Generate Composables in Android project build


    View Slide

  18. © ZOZO, Inc.
    18
    Generate code from UI package with Relay Gradle Plugin





    ● Generate Composables in Android project build

    ● The following two gradle tasks are defined:

    ○ generateRelayCode

    ○ generateRelayRuntimeCode

    ● Perform these tasks if you only want to build UI packages


    View Slide

  19. © ZOZO, Inc.
    19
    Relay workflow

    Figma
    Relay for Figma Plugin UI Packages
    Relay Gradle Plugin
    Relay for Android Studio Plugin
    Composables
    Components
    @Composable
    fun EventCard(modifier: Modifier =
    Modifier) {
    TopLevel(modifier = modifier) {
    Thumbnail()
    Title()
    Description()
    }
    }
    Android Studio
    Android Studio icon from: https://developer.android.com/studio

    View Slide

  20. © ZOZO, Inc.
    20
    Relay workflow

    Figma
    Relay for Figma Plugin UI Packages
    Relay Gradle Plugin
    Relay for Android Studio Plugin
    Composables
    Components
    @Composable
    fun EventCard(modifier: Modifier =
    Modifier) {
    TopLevel(modifier = modifier) {
    Thumbnail()
    Title()
    Description()
    }
    }
    Android Studio
    Android Studio icon from: https://developer.android.com/studio

    View Slide

  21. © ZOZO, Inc.
    21
    Make and propagate design updates


    View Slide

  22. © ZOZO, Inc.
    22
    Make and propagate design updates

    ● Update design and save named version


    View Slide

  23. © ZOZO, Inc.
    23
    Make and propagate design updates

    ● Update UI package in Android Studio

    ● Rebuild Android project to reflect updates


    View Slide

  24. © ZOZO, Inc.
    24
    What should I do in these cases?


    View Slide

  25. © ZOZO, Inc.
    25
    What should I do in these cases?

    ● Dynamically change text and images

    ● Handling Components with Multiple UI Patterns

    ● Handling clicks and other interactions


    View Slide

  26. © ZOZO, Inc.
    26
    Content parameters


    View Slide

  27. © ZOZO, Inc.
    27
    Content parameters

    ● Annotate where to parameterize the component


    View Slide

  28. © ZOZO, Inc.
    28
    Content parameters

    ● UI package updated to include parameters


    View Slide

  29. © ZOZO, Inc.
    29
    Content parameters

    ● Composable is generated to receive parameters


    View Slide

  30. © ZOZO, Inc.
    30
    Handling Design Variants


    View Slide

  31. © ZOZO, Inc.
    31
    Handling Design Variants

    ● Create Design Variants with Figma

    ● Relay can handle Variants

    ○ Switching Composables with enum


    View Slide

  32. © ZOZO, Inc.
    32
    Handling Design Variants

    ● Switching Composable with enum

    // Design to select for EventComponents
    enum class View {
    EventCard,
    ListItem
    }
    /**
    * This composable was generated from the UI Package 'event_components'.
    * Generated code; do not edit directly
    */
    @Composable
    fun EventComponents(
    modifier: Modifier = Modifier,
    view: View = View.EventCard
    ) {
    when (view) {
    View.EventCard -> TopLevelViewEventCard(modifier = modifier) {
    ThumbnailViewEventCard()
    TitleViewEventCard()
    DescriptionViewEventCard()
    }
    View.ListItem -> TopLevelViewListItem(modifier = modifier) {
    ThumbnailViewListItem()
    TextsViewListItem {
    TitleViewListItem()
    DescriptionViewListItem()
    OptionsViewListItem {
    OptionViewListItem()
    }
    }
    }
    }

    View Slide

  33. © ZOZO, Inc.
    33
    Handling Design Variants

    ● Switching Composable with enum

    // Design to select for EventComponents
    enum class View {
    EventCard,
    ListItem
    }
    /**
    * This composable was generated from the UI Package 'event_components'.
    * Generated code; do not edit directly
    */
    @Composable
    fun EventComponents(
    modifier: Modifier = Modifier,
    view: View = View.EventCard
    ) {
    when (view) {
    View.EventCard -> TopLevelViewEventCard(modifier = modifier) {
    ThumbnailViewEventCard()
    TitleViewEventCard()
    DescriptionViewEventCard()
    }
    View.ListItem -> TopLevelViewListItem(modifier = modifier) {
    ThumbnailViewListItem()
    TextsViewListItem {
    TitleViewListItem()
    DescriptionViewListItem()
    OptionsViewListItem {
    OptionViewListItem()
    }
    }
    }
    }

    View Slide

  34. © ZOZO, Inc.
    34
    Handling Design Variants

    ● Switching Composable with enum

    // Design to select for EventComponents
    enum class View {
    EventCard,
    ListItem
    }
    /**
    * This composable was generated from the UI Package 'event_components'.
    * Generated code; do not edit directly
    */
    @Composable
    fun EventComponents(
    modifier: Modifier = Modifier,
    view: View = View.EventCard
    ) {
    when (view) {
    View.EventCard -> TopLevelViewEventCard(modifier = modifier) {
    ThumbnailViewEventCard()
    TitleViewEventCard()
    DescriptionViewEventCard()
    }
    View.ListItem -> TopLevelViewListItem(modifier = modifier) {
    ThumbnailViewListItem()
    TextsViewListItem {
    TitleViewListItem()
    DescriptionViewListItem()
    OptionsViewListItem {
    OptionViewListItem()
    }
    }
    }
    }

    View Slide

  35. © ZOZO, Inc.
    35
    Handling Design Variants

    ● Switching Composable with enum

    // Design to select for EventComponents
    enum class View {
    EventCard,
    ListItem
    }
    /**
    * This composable was generated from the UI Package 'event_components'.
    * Generated code; do not edit directly
    */
    @Composable
    fun EventComponents(
    modifier: Modifier = Modifier,
    view: View = View.EventCard
    ) {
    when (view) {
    View.EventCard -> TopLevelViewEventCard(modifier = modifier) {
    ThumbnailViewEventCard()
    TitleViewEventCard()
    DescriptionViewEventCard()
    }
    View.ListItem -> TopLevelViewListItem(modifier = modifier) {
    ThumbnailViewListItem()
    TextsViewListItem {
    TitleViewListItem()
    DescriptionViewListItem()
    OptionsViewListItem {
    OptionViewListItem()
    }
    }
    }
    }

    View Slide

  36. © ZOZO, Inc.
    36
    Content Parameters in Design Variants

    ● Add content parameters to entire Design Variants


    View Slide

  37. © ZOZO, Inc.
    37
    /**
    * This composable was generated from the UI Package 'event_components'.
    * Generated code; do not edit directly
    *
    * @param thumbnail Event thumbnail image
    * @param title Event title
    * @param description Event description
    */
    @Composable
    fun EventComponents(
    modifier: Modifier = Modifier,
    view: View = View.EventCard,
    thumbnail: Painter = EmptyPainter(),
    title: String = "",
    description: String = ""
    ) {
    when (view) {
    View.EventCard -> TopLevelViewEventCard(modifier = modifier) {
    ThumbnailViewEventCard(thumbnail = thumbnail)
    TitleViewEventCard(title = title)
    DescriptionViewEventCard(description = description)
    }
    View.ListItem -> TopLevelViewListItem(modifier = modifier) {
    ThumbnailViewListItem(thumbnail = thumbnail)
    TextsViewListItem {
    TitleViewListItem(title = title)
    DescriptionViewListItem(description = description)
    OptionsViewListItem {
    OptionViewListItem()
    }
    }
    }
    }

    View Slide

  38. © ZOZO, Inc.
    38
    /**
    * This composable was generated from the UI Package 'event_components'.
    * Generated code; do not edit directly
    *
    * @param thumbnail Event thumbnail image
    * @param title Event title
    * @param description Event description
    */
    @Composable
    fun EventComponents(
    modifier: Modifier = Modifier,
    view: View = View.EventCard,
    thumbnail: Painter = EmptyPainter(),
    title: String = "",
    description: String = ""
    ) {
    when (view) {
    View.EventCard -> TopLevelViewEventCard(modifier = modifier) {
    ThumbnailViewEventCard(thumbnail = thumbnail)
    TitleViewEventCard(title = title)
    DescriptionViewEventCard(description = description)
    }
    View.ListItem -> TopLevelViewListItem(modifier = modifier) {
    ThumbnailViewListItem(thumbnail = thumbnail)
    TextsViewListItem {
    TitleViewListItem(title = title)
    DescriptionViewListItem(description = description)
    OptionsViewListItem {
    OptionViewListItem()
    }
    }
    }
    }

    View Slide

  39. © ZOZO, Inc.
    39
    Interaction Handlers


    View Slide

  40. © ZOZO, Inc.
    40
    Interaction Handlers

    ● Add Interaction Handlers to entire Design Variants


    View Slide

  41. © ZOZO, Inc.
    41
    @Composable
    fun EventComponents(
    modifier: Modifier = Modifier,
    view: View = View.EventCard,
    thumbnail: Painter = EmptyPainter(),
    title: String = "",
    description: String = "",
    onTapped: () -> Unit = {}
    ) {
    when (view) {
    View.EventCard -> TopLevelViewEventCard(
    onTapped = onTapped,
    modifier = modifier
    ) {
    ThumbnailViewEventCard(thumbnail = thumbnail)
    TitleViewEventCard(title = title)
    DescriptionViewEventCard(description = description)
    }
    View.ListItem -> TopLevelViewListItem(
    onTapped = onTapped,
    modifier = modifier
    ) {
    ThumbnailViewListItem(thumbnail = thumbnail)
    TextsViewListItem {
    TitleViewListItem(title = title)
    DescriptionViewListItem(description = description)
    OptionsViewListItem {
    OptionViewListItem()
    }
    }
    }
    }
    }

    View Slide

  42. © ZOZO, Inc.
    42
    @Composable
    fun EventComponents(
    modifier: Modifier = Modifier,
    view: View = View.EventCard,
    thumbnail: Painter = EmptyPainter(),
    title: String = "",
    description: String = "",
    onTapped: () -> Unit = {}
    ) {
    when (view) {
    View.EventCard -> TopLevelViewEventCard(
    onTapped = onTapped,
    modifier = modifier
    ) {
    ThumbnailViewEventCard(thumbnail = thumbnail)
    TitleViewEventCard(title = title)
    DescriptionViewEventCard(description = description)
    }
    View.ListItem -> TopLevelViewListItem(
    onTapped = onTapped,
    modifier = modifier
    ) {
    ThumbnailViewListItem(thumbnail = thumbnail)
    TextsViewListItem {
    TitleViewListItem(title = title)
    DescriptionViewListItem(description = description)
    OptionsViewListItem {
    OptionViewListItem()
    }
    }
    }
    }
    }

    View Slide

  43. © ZOZO, Inc.
    43
    Partially add Interaction Handlers

    ● Add interactions only for specific components


    View Slide

  44. © ZOZO, Inc.
    44
    @Composable
    fun EventComponents(
    modifier: Modifier = Modifier,
    view: View = View.EventCard,
    thumbnail: Painter = EmptyPainter(),
    title: String = "",
    description: String = "",
    onTapped: () -> Unit = {},
    onMenuTapped: () -> Unit = {}
    ) {
    when (view) {
    View.EventCard -> TopLevelViewEventCard(
    onTapped = onTapped,
    modifier = modifier
    ) {
    ThumbnailViewEventCard(thumbnail = thumbnail)
    TitleViewEventCard(title = title)
    DescriptionViewEventCard(description = description)
    }
    View.ListItem -> TopLevelViewListItem(
    onTapped = onTapped,
    modifier = modifier
    ) {
    ThumbnailViewListItem(thumbnail = thumbnail)
    TextsViewListItem {
    TitleViewListItem(title = title)
    DescriptionViewListItem(description = description)
    OptionsViewListItem {
    OptionViewListItem(onMenuTapped = onMenuTapped)
    }
    }
    }
    }
    }

    View Slide

  45. © ZOZO, Inc.
    45
    @Composable
    fun EventComponents(
    modifier: Modifier = Modifier,
    view: View = View.EventCard,
    thumbnail: Painter = EmptyPainter(),
    title: String = "",
    description: String = "",
    onTapped: () -> Unit = {},
    onMenuTapped: () -> Unit = {}
    ) {
    when (view) {
    View.EventCard -> TopLevelViewEventCard(
    onTapped = onTapped,
    modifier = modifier
    ) {
    ThumbnailViewEventCard(thumbnail = thumbnail)
    TitleViewEventCard(title = title)
    DescriptionViewEventCard(description = description)
    }
    View.ListItem -> TopLevelViewListItem(
    onTapped = onTapped,
    modifier = modifier
    ) {
    ThumbnailViewListItem(thumbnail = thumbnail)
    TextsViewListItem {
    TitleViewListItem(title = title)
    DescriptionViewListItem(description = description)
    OptionsViewListItem {
    OptionViewListItem(onMenuTapped = onMenuTapped)
    }
    }
    }
    }
    }

    View Slide

  46. © ZOZO, Inc.
    46
    Add state and interaction

    ● UI package is stateless

    ● Wrap your generated package in a custom Composable function for state
    management

    ● For example, if the DropdownMenu is displayed by clicking on the menu


    View Slide

  47. © ZOZO, Inc.
    47
    @Composable
    fun EventListItemController(
    event: Event,
    onTapped: () -> Unit,
    ) {
    var expanded by remember { mutableStateOf(false) }
    Box {
    EventComponents(

    view = View.ListItem,
    onTapped = onTapped,
    onMenuTapped = {
    expanded = true
    }
    )
    DropdownMenu(
    expanded = expanded,
    onDismissRequest = { expanded = false },
    ) {
    DropdownMenuItem(
    text = { Text(text = "menu1") },
    onClick = { /*TODO*/ }
    )

    }
    }
    }

    View Slide

  48. © ZOZO, Inc.
    48
    @Composable
    fun EventListItemController(
    event: Event,
    onTapped: () -> Unit,
    ) {
    var expanded by remember { mutableStateOf(false) }
    Box {
    EventComponents(

    view = View.ListItem,
    onTapped = onTapped,
    onMenuTapped = {
    expanded = true
    }
    )
    DropdownMenu(
    expanded = expanded,
    onDismissRequest = { expanded = false },
    ) {
    DropdownMenuItem(
    text = { Text(text = "menu1") },
    onClick = { /*TODO*/ }
    )

    }
    }
    }

    View Slide

  49. © ZOZO, Inc.
    49
    What should I do in these cases?

    ● Dynamically change text and images

    ● Handling Components with Multiple UI Patterns

    ● Handling clicks and other interactions


    View Slide

  50. © ZOZO, Inc.
    50
    What should I do in these cases?

    ● Dynamically change text and images

    → Content Parameters

    ● Handling Components with Multiple UI Patterns

    → Switching in Design Variants

    ● Handling clicks and other interactions

    → Interaction Handlers


    View Slide

  51. © ZOZO, Inc.
    51

    View Slide

  52. © ZOZO, Inc.
    52
    Other Features

    ● Mapping Figma’s Styles to Compose theme

    ● Mapping components to existing code


    View Slide

  53. © ZOZO, Inc.
    53
    Pros & Cons

    ● Composables generated from design files are considered accurate

    ● Easy Android app development with UI package

    ● Need to design with the generated code in mind, for better or worse

    ● Roles of designers and engineers need to be reconsidered


    View Slide

  54. © ZOZO, Inc.
    54
    Conclusion

    ● Design and Android app development are closely connected

    ● It is exciting to see Composable being generated from Figma!

    ○ This is an α release and I look forward to future updates

    ● A lot of thinking to ask into the development process, but much potential
    for productivity improvement.


    View Slide

  55. © ZOZO, Inc.
    55
    How to study Relay?

    ● Watch “Build a complete app with Relay and Compose”

    ● Do Codelab

    ● Read the Android Developers documentation

    ● Hands on (good if you can do it with a designer)


    View Slide

  56. View Slide