环境配置与项目搭建
1. Gradle 依赖配置
// build.gradle (Module)
android {
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion "1.5.3"
}
}
dependencies {
def wear_compose_version = "1.2.0"
implementation "androidx.wear.compose:compose-material:$wear_compose_version"
implementation "androidx.wear.compose:compose-foundation:$wear_compose_version"
implementation "androidx.wear.compose:compose-navigation:$wear_compose_version"
implementation "androidx.activity:activity-compose:1.8.0"
// 添加健康服务支持
implementation "androidx.health:health-services-client:1.0.0-beta02"
}
核心组件深度解析
1. 自适应布局容器
@Composable
fun HealthDataScreen() {
val scrollState = rememberScalingLazyListState()
ScalingLazyColumn(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colors.background),
state = scrollState,
anchorType = ScalingLazyListAnchorType.ItemStart
) {
item {
Header(
modifier = Modifier.padding(8.dp),
text = "健康数据监测"
)
}
items(healthItems) { item ->
HealthChip(
item = item,
onItemClick = { navigateToDetail(item.id) }
)
}
item {
Spacer(modifier = Modifier.height(16.dp))
CircularProgressIndicator(
modifier = Modifier
.size(24.dp)
.align(Alignment.CenterHorizontally)
)
}
}
TimeText(
modifier = Modifier.scrollAway(scrollState),
timeSource = TimeTextDefaults.timeSource(
timeFormat = "HH:mm",
timeZone = TimeZone.currentSystemDefault()
)
)
}
@Composable
fun HealthChip(item: HealthItem, onItemClick: () -> Unit) {
Chip(
modifier = Modifier.padding(4.dp),
onClick = onItemClick,
colors = ChipDefaults.chipColors(
backgroundColor = MaterialTheme.colors.surface,
contentColor = MaterialTheme.colors.onSurface
),
border = ChipDefaults.chipBorder(
borderWidth = 1.dp,
borderColor = MaterialTheme.colors.outline
),
label = {
Text(
text = item.title,
style = MaterialTheme.typography.body2
)
},
icon = {
Icon(
imageVector = item.icon,
contentDescription = null,
modifier = Modifier.size(24.dp)
}
)
}
2. 健康数据集成实现
class HealthDataManager(context: Context) {
private val healthClient = HealthServices.getClient(context)
private var heartRateListener: HeartRateListener? = null
suspend fun startHeartRateMonitoring() {
val request = SensorRegistrationRequest(
sensorType = SensorType.HEART_RATE,
reportingMode = ReportingMode.RECEIVE_IF_INACTIVE,
sampleInterval = 5.seconds
)
try {
healthClient.registerSensorListener(
object : HeartRateListener {
override fun onHeartRateUpdate(data: HeartRateData) {
// 更新UI或存储数据
Log.d("Health", "当前心率: ${data.value} BPM")
}
},
request
)
} catch (e: Exception) {
Log.e("Health", "传感器注册失败", e)
}
}
fun stopMonitoring() {
heartRateListener?.let {
healthClient.unregisterSensorListener(it)
}
}
}
// 在ViewModel中使用
class HealthViewModel(application: Application) : AndroidViewModel(application) {
private val healthManager = HealthDataManager(application)
init {
viewModelScope.launch {
healthManager.startHeartRateMonitoring()
}
}
override fun onCleared() {
healthManager.stopMonitoring()
super.onCleared()
}
}
高级导航架构
1. 分层导航实现
@Composable
fun WearApp() {
val navController = rememberSwipeDismissableNavController()
SwipeDismissExample(navController) {
NavHost(
navController = navController,
startDestination = Screen.Main.route
) {
composable(Screen.Main.route) {
MainScreen(
onNavigateToDetail = { id ->
navController.navigate("${Screen.Detail.route}/$id")
}
)
}
composable(
route = "${Screen.Detail.route}/{id}",
arguments = listOf(navArgument("id") { type = NavType.IntType })
) { backStackEntry ->
DetailScreen(
itemId = backStackEntry.arguments?.getInt("id") ?: 0,
onBack = { navController.popBackStack() }
)
}
}
}
}
sealed class Screen(val route: String) {
object Main : Screen("main")
object Detail : Screen("detail")
}
设备适配策略
1. 多形态屏幕适配
@Composable
fun AdaptiveLayout() {
val windowInfo = rememberWindowInfo()
when (windowInfo.devicePosture) {
is DevicePosture.Flat -> {
// 普通模式布局
StandardLayout()
}
is DevicePosture.HalfOpened -> {
// 折叠半开模式
HalfOpenLayout()
}
else -> {
// 默认布局
DefaultLayout()
}
}
}
@Composable
fun rememberWindowInfo(): WindowInfo {
val context = LocalContext.current
val windowInfo = remember {
WindowInfoRepository.getOrCreate(context)
}
return windowInfo
}
性能优化实践
1. 智能缓存策略
@Composable
fun ComplexDataView() {
val viewModel: HealthViewModel = viewModel()
val dataState by viewModel.complexDataState.collectAsState()
when (dataState) {
is DataState.Loading -> ShowLoading()
is DataState.Success -> ShowData((dataState as DataState.Success).data)
is DataState.Error -> ShowError()
}
}
class HealthViewModel : ViewModel() {
private val _complexDataState = mutableStateOf<DataState>(DataState.Loading)
val complexDataState: State<DataState> = _complexDataState
init {
loadData()
}
private fun loadData() {
viewModelScope.launch {
_complexDataState.value = DataState.Loading
try {
val result = computeExpensiveData()
_complexDataState.value = DataState.Success(result)
} catch (e: Exception) {
_complexDataState.value = DataState.Error(e.message)
}
}
}
private suspend fun computeExpensiveData(): HealthData {
return withContext(Dispatchers.Default) {
// 模拟复杂计算
delay(1000)
HealthData(...)
}
}
}
发布配置与优化
1. 构建配置最佳实践
android {
defaultConfig {
minSdk 26
targetSdk 34
versionCode generateVersionCode()
versionName "2.1.0-wear"
// Wear OS 专属配置
resConfigs "en", "zh-rCN"
wearAppUnbundled true
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}
def generateVersionCode() {
return (new Date().format('yyyyMMddHH').toInteger())
}
关键注意事项
交互设计规范
- 保持单次交互在5秒内完成
- 所有可点击区域 ≥ 48dp
- 优先使用系统级手势(如右滑返回)
功耗优化
fun updateDataStrategy() { if (isAmbientMode) { // 省电模式更新间隔 setUpdateInterval(60_000L) } else { setUpdateInterval(1_000L) } }
Always-on Display 适配
@Composable fun AmbientModeAwareText(text: String) { val ambientState = ambientAware() Text( text = if (ambientState.isAmbient) simplifyText(text) else text, color = if (ambientState.isAmbient) Color.White else MaterialTheme.colors.primary, style = MaterialTheme.typography.body1 ) }
测试与验证
性能基准测试
@RunWith(AndroidJUnit4::class) class PerformanceTest { @get:Rule val rule = createComposeRule() @Test fun testMainScreenPerformance() { rule.setContent { MainScreen() } rule.onRoot().assertNoIdleResources() rule.waitForIdle() // 测量帧率 val stats = rule.frameStats() assertThat(stats.avgFps).isGreaterThan(45) } }
功耗监测
adb shell dumpsys batterystats --reset # 执行测试用例 adb shell dumpsys batterystats --charged <package_name>
总结与最佳实践
通过上述完整实现方案,我们构建了一个符合 Wear OS 设计规范的健壮应用。关键实践包括:
- 分层架构设计:清晰的 ViewModel + Repository 结构
- 响应式 UI:充分利用 Compose 的状态管理
- 性能优先:智能数据加载策略和计算缓存
- 设备感知:自适应不同穿戴设备形态
- 健康数据集成:规范使用 Health Services API
建议结合最新 Wear OS 设计指南进行以下优化:
- 实现 Material You 动态主题
- 添加触觉反馈(Haptic Feedback)
- 集成 Google 健身数据平台
- 支持跨设备数据同步