了解 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 视图中,这些显示为模块目录(在本例中为 app 目录)下的 java (generated)res

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 = {}
) {...}