2. 项目环境搭建:Android Studio配置、Gradle依赖引入、Material 3主题设置、最低API版本要求

安全输入组件依赖完整的 Material 3 组件生态和 Android 编译链。环境搭建阶段需要精确控制 SDK 版本、Gradle 插件版本、Material 3 依赖坐标以及最低 API 门槛。任何版本错配都会导致 TextFields 样式丢失、PasswordVisualTransformation 不可用或编译时符号缺失。本章按「编辑器 → 构建系统 → 依赖 → 主题 → 验证」的链路逐一建立基线。

基线版本快照(2025 Q2 稳定组合):AGP 8.2+、Kotlin 1.9.22、Gradle 8.5+、Material 3 1.2.x、minSdk 24。

2.1 Android Studio 与 Gradle 配置

推荐使用 Android Studio Ladybug(2024.2.1)或更高版本,内置 K2 编译器可获得更快的 IDE 响应。项目创建后首先检查 gradle-wrapper.properties,确保 Gradle 发行版 ≥ 8.5:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

根项目 build.gradle.kts 中声明插件版本与仓库:

plugins {
    id("com.android.application") version "8.2.2" apply false
    id("org.jetbrains.kotlin.android") version "1.9.22" apply false
}

allprojects {
    repositories {
        google()
        mavenCentral()
    }
}
避坑点:不要使用 AGP 8.1 以下版本,否则 @OptIn(ExperimentalMaterial3Api::class) 注解无法正常编译;不要混合使用 Groovy 与 KTS 脚本,统一采用 .kts 后缀。

2.2 Gradle 依赖引入——精确坐标与功能分组

安全输入组件涉及的依赖可分为三组:Material 3 基础库、图标扩展 与 可访问性工具。在模块级 build.gradle.kts 中按组引入:

// —— Material 3 基础库 ——
implementation("androidx.compose.material3:material3:1.2.1")
implementation("androidx.compose.material3:material3-window-size-class:1.2.1")

// —— 图标与视觉转换 ——
implementation("androidx.compose.material:material-icons-extended:1.6.7")

// —— Compose 编译器与运行时 ——
implementation("androidx.compose.ui:ui:1.6.7")
implementation("androidx.compose.ui:ui-tooling-preview:1.6.7")
implementation("androidx.activity:activity-compose:1.9.0")
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.8.0")

// —— 可访问性:用于安全输入组件的标签与操作 ——
implementation("androidx.compose.ui:ui-test-junit4:1.6.7")
implementation("androidx.compose.ui:ui-test-manifest:1.6.7")
为什么必须显式引入 material-icons-extended?
安全输入组件中的密码可见切换图标(Visibility / VisibilityOff)位于扩展图标集中。如果不引入该依赖,运行时会抛出 FontNotFoundException。

2.3 Material 3 主题设置——配色、形状与字体

安全输入组件的错误状态、聚焦指示器、标签动画都直接从主题槽中读取颜色令牌。在 Theme.kt 中定义基于 Material 3 的 MaterialTheme:

// Theme.kt
private val LightColorScheme = lightColorScheme(
    primary = Color(0xFF1976D2),
    onPrimary = Color.White,
    primaryContainer = Color(0xFFBBDEFB),
    error = Color(0xFFD32F2F),
    onError = Color.White,
    errorContainer = Color(0xFFFFCDD2),
    surface = Color.White,
    onSurface = Color(0xFF212121)
)

private val DarkColorScheme = darkColorScheme(
    primary = Color(0xFF90CAF9),
    onPrimary = Color(0xFF0D47A1),
    primaryContainer = Color(0xFF1565C0),
    error = Color(0xFFEF9A9A),
    onError = Color(0xFFB71C1C),
    errorContainer = Color(0xFFC62828),
    surface = Color(0xFF121212),
    onSurface = Color(0xFFE0E0E0)
)

@Composable
fun SecurityInputTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    val colorScheme = if (darkTheme) DarkColorScheme else LightColorScheme
    MaterialTheme(
        colorScheme = colorScheme,
        shapes = Shapes(
            small = RoundedCornerShape(8.dp),
            medium = RoundedCornerShape(12.dp),
            large = RoundedCornerShape(16.dp)
        ),
        content = content
    )
}
必须覆盖 errorContainer 和 onError:安全输入组件的校验失败提示、边框颜色、辅助文本均依赖这两个令牌。如果使用默认值,在深色模式下错误状态可能不可见。

2.4 最低 API 版本要求——minSdk 决策依据

Material 3 的 OutlinedTextField 与 PasswordVisualTransformation 在 API 24+ 上经过完整测试。低于 API 24 的设备无法保证 TextInputLayout 动画流畅,且 BiometricPrompt(安全输入可选集成)仅在 API 28+ 提供稳定 API。

组件 / 特性 最低 API 版本 说明
OutlinedTextField + 密码转换 24 强制 minSdk = 24,兼容 99% 活跃设备
BiometricPrompt 集成 28 可选特性,通过 @RequiresApi 条件触发
Material 3 动态颜色 31 通过 dynamicLightColorScheme 支持
安全输入辅助功能标签 24 semantics 修饰符全版本可用

在 build.gradle.kts 的 defaultConfig 块中设置:

defaultConfig {
    applicationId = "com.example.securityinput"
    minSdk = 24
    targetSdk = 34
    versionCode = 1
    versionName = "1.0.0"

    testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    vectorDrawables {
        useSupportLibrary = true
    }
}
兼容性策略:如果项目需要支持 API 23 以下设备,建议放弃 Material 3 安全输入组件,回退到 AppCompat TextInputEditText + 自定义密码切换。本课程所有示例均以 minSdk 24 为基线。

2.5 环境验证——编译检查与预览渲染

完成上述配置后执行三步验证。首先运行 Gradle 同步,确认无红色波浪线;然后执行编译检查:

./gradlew assembleDebug --daemon --build-cache

编译成功后在 MainActivity.kt 中写入最小预览代码,验证主题与组件是否正常渲染:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            SecurityInputTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.surface
                ) {
                    OutlinedTextField(
                        value = "",
                        onValueChange = { },
                        label = { Text("密码") },
                        visualTransformation = PasswordVisualTransformation(),
                        leadingIcon = {
                            Icon(Icons.Default.Lock, contentDescription = "密码图标")
                        }
                    )
                }
            }
        }
    }
}

在模拟器(API 24+)或真机上运行,应当看到带密码掩码的输入框,点击图标区域无崩溃。如果预览报错 ComposeViewAdapter 异常,请检查 build.gradle.kts 中是否遗漏 ui-tooling-preview 依赖。

2.6 整体搭建流程

下图汇总了从 Android Studio 配置到最终验证的完整链路,每个方框对应一个可追溯的检查点:

项目环境搭建流程图 环境搭建流程与关键检查点 1. AS + Gradle 配置 AGP 8.2 / Gradle 8.5 2. Gradle 依赖引入 material3 + icons-extended 3. Material 3 主题 配色 / 形状 / 字体 4. minSdk = 24 决策 兼容 99% 活跃设备 5. 编译检查 ./gradlew assembleDebug 6. 预览 & 真机运行 OutlinedTextField 渲染 ✅ 环境就绪 可进入下一章 🔍 关键检查点 确认 AGP / Gradle / material3 / minSdk 版本匹配;预览无崩溃;错误颜色令牌正确

2.7 常见错误与调试技巧

错误现象 根因 解决方案
Cannot find icon: Visibility 缺少 material-icons-extended 添加依赖并重新同步 Gradle
@OptIn(ExperimentalMaterial3Api::class) 编译失败 AGP < 8.2 或 Kotlin < 1.9.0 升级 AGP 到 8.2+,Kotlin 到 1.9.22
预览窗格空白,报 ComposeViewAdapter 异常 缺少 ui-tooling-preview 或编译器版本不匹配 确认 ui-tooling-preview 版本与 ui 一致
深色模式下错误提示不可见 未覆盖 errorContainer / onError 在 darkColorScheme 中显式赋值
minSdk 24 项目无法安装到 API 23 设备 最小 API 门槛设定 如需兼容,使用 AppCompat 方案替代
性能提示:material-icons-extended 体积约 5.5 MB。如果仅使用密码可见/隐藏两个图标,可以改用 Icons.Default 中的 Lock / LockOpen 并跳过扩展库。但课程后续章节会用到更多安全图标(指纹、密钥等),因此建议保留完整扩展库。

2.8 搭建后检查清单

  • ☐ gradle-wrapper.properties 中 distributionUrl 指向 Gradle 8.5+
  • ☐ 模块级 build.gradle.kts 包含 material3:1.2.x 与 material-icons-extended
  • ☐ SecurityInputTheme 覆盖 errorContainer 和 onError 颜色令牌
  • ☐ minSdk = 24 已生效,targetSdk = 34
  • ☐ ./gradlew assembleDebug 编译通过
  • ☐ 预览或真机运行显示密码掩码输入框,无崩溃、无图标缺失
进阶调试:在 gradle.properties 中添加 android.enableJetifier=false(Material 3 已完全迁移到 AndroidX),并开启 kotlin.code.style=official 统一代码风格。后续所有安全输入组件代码都将在本章搭建的环境上迭代。