将 Jetpack Compose 添加到应用中

如果您想要在现有项目中使用 Jetpack Compose,则需要为项目配置所需的设置和依赖项。

设置您的开发环境

安装合适的 Android Studio 版本

为了在使用 Jetpack Compose 进行开发时获得最佳体验,您应下载 Android Studio Arctic Fox,并配置与 Android Studio 版本对应的 Android Gradle 插件:

buildscript {
    ...
    dependencies {
        classpath "com.android.tools.build:gradle:7.0.0"
        ...
    }
}

配置 Kotlin

确保您在项目中使用的是 Kotlin 1.5.21:

plugins {
    id 'org.jetbrains.kotlin:android' version '1.5.21'
}

配置 Gradle

您需要将应用的最低 API 级别设置为 21 或更高级别,并在应用的 build.gradle 文件中启用 Jetpack Compose,如下所示。另外还要设置 Kotlin 编译器插件的版本。

android {
    defaultConfig {
        ...
        minSdkVersion 21
    }

    buildFeatures {
        // Enables Jetpack Compose for this module
        compose true
    }
    ...

    // Set both the Java and Kotlin compilers to target Java 8.
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }

    composeOptions {
        kotlinCompilerExtensionVersion '1.0.1'
    }
}

添加 Jetpack Compose 工具包依赖项

在应用的 build.gradle 文件中添加 Jetpack Compose 工具包依赖项,如下所示:

dependencies {
    // Integration with activities
    implementation 'androidx.activity:activity-compose:1.3.1'
    // Compose Material Design
    implementation 'androidx.compose.material:material:1.0.1'
    // Animations
    implementation 'androidx.compose.animation:animation:1.0.1'
    // Tooling support (Previews, etc.)
    implementation 'androidx.compose.ui:ui-tooling:1.0.1'
    // Integration with ViewModels
    implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:1.0.0-alpha07'
    // UI Tests
    androidTestImplementation 'androidx.compose.ui:ui-test-junit4:1.0.1'
}

在 Compose 中重复使用视图主题

如果您刚刚将 Compose 添加到项目中,则可能需要 Compose 继承 View 系统中可用的主题,而不是从头开始在 Compose 中重新编写自己的 Material 主题。

如果您在 Android 应用中使用 MDC 库,则可借助 MDC Compose 主题适配器库,在可组合项中轻松地重复使用基于 View 的现有主题的颜色、排版和形状主题。这可通过 MdcTheme API 来实现。

如果您改为使用 AppCompat XML 主题,请使用包含 AppCompatTheme API 的 AppCompat Compose 主题适配器

在应用的 build.gradle 文件中添加所需的依赖项,如下所示:

dependencies {
    // When using a MDC theme
    implementation "com.google.android.material:compose-theme-adapter:1.0.1"

    // When using a AppCompat theme
    implementation "com.google.accompanist:accompanist-appcompat-theme:0.16.0"
}

开始迁移到 Compose

假设我们要在应用中将用户问候文本迁移到 Jetpack Compose。我们可以在 XML 布局中添加以下内容:

<...>
    <!-- Other content -->

    <TextView
        android:id="@+id/greeting"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/margin_small"
        android:layout_marginEnd="@dimen/margin_small"
        android:gravity="center_horizontal"
        android:text="@string/greeting"
        android:textAppearance="?attr/textAppearanceHeadline5"
        ... />
</...>

为了将其迁移到 Compose,我们可以将 View 替换为保留了相同布局参数和 idComposeView

<...>
    <!-- Other content -->

    <androidx.compose.ui.platform.ComposeView
        android:id="@+id/greeting"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</...>

然后,在使用了该 XML 布局的 ActivityFragment 中,我们可以获取 ComposeView,并调用 setContent 方法,以向其中添加 Compose 内容:

class MyActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...

        val greeting = findViewById<ComposeView>(R.id.greeting)
        greeting.setContent {
            MdcTheme { // or AppCompatTheme
                Greeting()
            }
        }
    }
}

@Composable
private fun Greeting() {
    Text(
        text = stringResource(R.string.greeting),
        style = MaterialTheme.typography.h5,
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = dimensionResource(R.dimen.margin_small))
            .wrapContentWidth(Alignment.CenterHorizontally)
    )
}

如需详细了解 ComposeView 和其他 Interoperability API,请参阅 Interoperability API 指南。如需详细了解 Compose 中的 stringResourcedimensionResource 和其他资源 API,请查看“Compose 中的资源”指南

测试混合界面

将应用的某些部分迁移到 Compose 后,若要确保您没有破坏任何内容,测试至关重要。

当 activity 或 fragment 使用 Compose 时,您无需使用 ActivityScenarioRule,而应该使用 createAndroidComposeRule,它将 ActivityScenarioRuleComposeTestRule 集成,让您可以同时测试 Compose 和 View 代码。

class MyActivityTest {
    @Rule
    @JvmField
    val composeTestRule = createAndroidComposeRule<MyActivity>()

    @Test
    fun testGreeting() {
        val greeting = InstrumentationRegistry.getInstrumentation()
            .targetContext.resources.getString(R.string.greeting)

        composeTestRule.onNodeWithText(greeting).assertIsDisplayed()
    }
}

请参阅“测试 Compose 布局”指南,详细了解测试以及与 Espresso 的互操作性

在架构中集成 Compose

Compose 支持大多数应用架构,并提供了与许多其他常用库的集成。因此,您无需更改层次结构的其他层,即可开始在应用中使用 Compose。

以下代码段展示了 Compose 如何通过 viewModel() 函数与架构组件 ViewModel 搭配使用,并使用 collectAsState() 从 Kotlin Flow 中收集信息。

class MyActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyScreen()
        }
    }
}

@Composable
private fun MyScreen(
    viewModel: MyViewModel = viewModel()
) {
    val uiState by viewModel.uiState.collectAsState()
    when {
        uiState.isLoading -> { /* ... */ }
        uiState.isSuccess -> { /* ... */ }
        uiState.isError -> { /* ... */ }
    }
}

class MyViewModel : ViewModel() {
    private val _uiState = MutableStateFlow(MyScreenState.Loading)
    val uiState: StateFlow<MyScreenState> = _uiState
}

如需了解图像加载、Paging 或 Hilt 等更多集成,请参阅“Compose 和其他库”指南

如果您在应用中使用了导航组件,请查看“使用 Compose 进行导航”指南中的“互操作性”部分

后续步骤

如需详细了解 Compose,请参阅文档索引。在应用中采用 Compose 的方法有很多种,如需详细了解这方面的内容,请参阅“在应用中采用 Compose”指南,其中还链接到在现有架构中集成 Compose在现有界面中集成 Compose 等其他指南。