了解 UI 包和生成代码

UI 包

UI 包是一种交换 UI 信息的新型灵活方式。设计师使用 Relay for Figma 插件从 Figma 中的组件创建 UI 包。这样做表示设计已准备好供开发人员使用。然后,设计师向开发人员提供其 Figma 设计文件的 URL。

开发人员使用 Android Studio 插件从 Figma 设计文件导入 UI 包。在 Android Studio 项目中,UI 包包含导入的 Figma 组件的声明性描述以及相关资产,包括字体文件、图像和 SVG。

UI 包是持久性工件,可以提交到源代码控制。当开发人员在 Android Studio 项目中导入 Figma 包时,文件将添加到 ui-packages 文件夹中的项目中。这是一个导入的 UI 包示例

Content of a UI Package

包含导入的 UI 包的项目包含以下文件

  • [component_name].json — 描述组件的 JSON 文件(例如,story_card.json)。
  • config.json — 存储特定 UI 包的元数据。
  • fonts/ — 存储组件使用的字体资产的文件夹(如果有)。
  • *.png — 组件中使用的图像资产(例如,menu.png)(如果有)。
  • [component_name]_preview.png — 组件的预览图像(例如,story_card_preview.png)。
  • *.svg — 组件中使用的矢量图形资产(例如,三角形)(如果有)。
  • FONTS.txt — 使用的字体列表(如果有)。
  • DEPS.txt — 任何子组件的名称。
  • VERSION.txt — 用于创建和导入 UI 包的 Relay 版本。

这些存储在 src/main/ui-packages/[package_name] 下。

删除 UI 包

要从项目中删除 UI 包,您可以删除 ui-packages/ 下的文件夹。删除文件夹后重建项目也会删除其生成的代码。

生成的代码文件夹结构

项目构建时,这些 UI 包将转换为包含 @Composable 函数的生成代码,开发人员可以调用这些函数。这些存储在 build/generated/ 下。在 Android 视图中,这些显示为 java (generated)res,位于您的模块目录下(在本例中为 app 目录)。

Folders that contain generated files in Android studio

以下屏幕截图介绍了此目录中的文件

  • 资源(例如字体和图像)将复制到 build/generated/res/relay/

    Generated resources under the res folder
  • 每个 UI 包的生成代码都放置在 build/generated/source/relay/ 下。每个 UI 包的生成代码文件夹都有一个与导入的组件相对应文件。它还包含一个以 Fonts.kt 结尾的文件,其中包含对组件使用的字体资产的引用。

    Generated Kotlin files under the java(generated) folder
  • 还有一个运行时库 com.google.relay.compose,它提供了生成代码使用的功能。

    Relay runtime library

生成的代码结构

可组合项

Figma 中的组件由图层组成。例如,此设计包含一个框架图层Hello Card,其中包含两个子图层,Image(图像图层)和Title(文本图层)

Hello Card component with Image and Title layers

将此设计转换为代码时,我们会为每个图层创建单独的可组合函数,其中 Figma 图层的名称是可组合函数的名称(修改为符合 Kotlin 语法)。图层转换如下

  1. Hello Card 图层

    @Composable
    fun HelloCard(
      modifier: Modifier = Modifier,
      title: String
    ) {
      TopLevel(modifier = modifier) {
          Image()
          Title(title = title)
      }
    ]
    
  2. Image 图层

    @Composable
    fun Image(modifier: Modifier = Modifier) {
      Image(...)
    }
    
  3. Title 图层

    @Composable
    fun Title(
      title: String,
      modifier: Modifier = Modifier
    ) {
      Text(...)
    }
    

转换后的 Figma 变体和参数

如果 Figma 组件有多个变体,则生成的代码会为每个变体属性包含一个枚举。每个变体枚举中的值对应于该变体属性的值。可组合项包括每个变体枚举的参数。

// Design to select for NewsCard
enum class View {
    HeroItem,
    ArticleItem,
    AudioItem
}

/**
 *   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,
    onNewsCardTapped: () -> Unit = {},
    thumbnail: Painter,
    headline: String,
    author: String,
    date: String,
    onMenuTapped: () -> Unit = {}
) {
       when (view) {
           View.HeroItem -> TopLevelViewHeroItem(...) {
               ContentViewHeroItem { ... }
           }
           View.ArticleItem -> TopLevelViewArticleItem(...) {
               ContentViewArticleItem { ... }
           }
           View.AudioItem -> TopLevelViewAudioItem(...) {
               ContentViewAudioItem { ... }
           }
       }
   }
}

Figma 组件的每个内容参数和交互处理程序都将转换为可组合项的参数。NewsCard 可组合项下面有四个内容参数(一个图像和三个字符串)和两个交互处理程序(最后两个参数)。

/**
 *   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,
    headline: String,
    author: String,
    date: String,
    onNewsCardTapped: () -> Unit = {},
    onMenuTapped: () -> Unit = {}
) {...}