新增设备列表 Compose 页面 #8

Merged
KremeCN merged 4 commits from feature/device-control-compose-ui into main 2026-08-25 11:39:12 +08:00
5 changed files with 90 additions and 25 deletions
Showing only changes of commit ae488ef8c3 - Show all commits
@@ -0,0 +1,54 @@
package com.flagship.abox.manager.ui.devicecontrollist
import androidx.activity.ComponentActivity
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.flagship.abox.manager.R
import com.flagship.abox.manager.designsystem.ABoxTheme
import org.junit.Assert.assertEquals
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class DeviceListScreenTest {
@get:Rule
val composeRule = createAndroidComposeRule<ComponentActivity>()
@Test
fun deviceListRendersAllDeviceCategoryButtonsAndHandlesClicks() {
var socketClicks = 0
var tempClicks = 0
var infraredClicks = 0
val context = composeRule.activity
val socketTitle = context.getString(R.string.device_socket_title)
val tempTitle = context.getString(R.string.device_temperature_humidity_title)
val infraredTitle = context.getString(R.string.device_infrared_title)
val listTitle = context.getString(R.string.device_list_title)
composeRule.setContent {
ABoxTheme {
DeviceListScreen(
onSocketClick = { socketClicks++ },
onTemperatureHumidityClick = { tempClicks++ },
onInfraredClick = { infraredClicks++ },
)
}
}
composeRule.onNodeWithText(listTitle).assertIsDisplayed()
composeRule.onNodeWithText(socketTitle).assertIsDisplayed().performClick()
assertEquals(1, socketClicks)
composeRule.onNodeWithText(tempTitle).assertIsDisplayed().performClick()
assertEquals(1, tempClicks)
composeRule.onNodeWithText(infraredTitle).assertIsDisplayed().performClick()
assertEquals(1, infraredClicks)
}
}
@@ -12,18 +12,20 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.flagship.abox.manager.R
import com.flagship.abox.manager.designsystem.ABoxButton
import com.flagship.abox.manager.designsystem.ABoxTheme
@Composable
fun DeviceListScreen(
onSocketClick: () -> Unit,
onTemperatureHumidityClick: () -> Unit,
onInfraredClick: () -> Unit,
modifier: Modifier = Modifier,
onSocketClick: () -> Unit = {},
onTemperatureHumidityClick: () -> Unit = {},
onInfraredClick: () -> Unit = {},
) {
Column(
modifier = modifier
@@ -34,29 +36,29 @@ fun DeviceListScreen(
verticalArrangement = Arrangement.Center,
) {
Text(
text = "设备列表",
text = stringResource(R.string.device_list_title),
style = MaterialTheme.typography.headlineLarge,
textAlign = TextAlign.Center,
)
Text(
text = "选择需要控制或查看状态的 ABox 终端设备。",
text = stringResource(R.string.device_list_description),
modifier = Modifier.padding(top = 12.dp, bottom = 32.dp),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center,
)
DeviceEntryButton(
text = "智能插座",
description = "进入智能插座相关功能。",
text = stringResource(R.string.device_socket_title),
description = stringResource(R.string.device_socket_description),
onClick = onSocketClick,
)
DeviceEntryButton(
text = "温湿度传感器",
description = "进入温湿度状态相关功能。",
text = stringResource(R.string.device_temperature_humidity_title),
description = stringResource(R.string.device_temperature_humidity_description),
onClick = onTemperatureHumidityClick,
)
DeviceEntryButton(
text = "红外控制器",
description = "进入红外控制器相关功能。",
text = stringResource(R.string.device_infrared_title),
description = stringResource(R.string.device_infrared_description),
onClick = onInfraredClick,
)
}
@@ -88,10 +90,6 @@ private fun DeviceEntryButton(
@Composable
private fun DeviceListScreenPreview() {
ABoxTheme {
DeviceListScreen(
onSocketClick = {},
onTemperatureHumidityClick = {},
onInfraredClick = {},
)
DeviceListScreen()
}
}
@@ -29,6 +29,7 @@ import com.flagship.abox.manager.R
import com.flagship.abox.manager.designsystem.ABoxNavigationBar
import com.flagship.abox.manager.designsystem.ABoxNavigationBarItem
import com.flagship.abox.manager.designsystem.ABoxTopPillBar
import com.flagship.abox.manager.ui.devicecontrollist.DeviceListScreen
/**
* Main authenticated application shell.
@@ -50,7 +51,7 @@ fun MainAppShell(
onAddClick: (() -> Unit)? = null,
actionInProgress: Boolean = false,
errorMessage: String? = null,
devicesSlot: @Composable () -> Unit = { DefaultDevicesSlot() },
devicesSlot: @Composable () -> Unit = { DeviceListScreen() },
scenesSlot: @Composable () -> Unit = { DefaultScenesSlot() },
Review

无效入口

MainAppShell 默认直接创建 DeviceListScreen(),但没有传入任何点击回调,因此三个设备按钮都会使用空实现。任何未显式覆盖 devicesSlot 的调用方都会展示可点击但无响应的入口;应在路由完成前保留占位内容,或由壳层传入实际回调。

**无效入口** `MainAppShell` 默认直接创建 `DeviceListScreen()`,但没有传入任何点击回调,因此三个设备按钮都会使用空实现。任何未显式覆盖 `devicesSlot` 的调用方都会展示可点击但无响应的入口;应在路由完成前保留占位内容,或由壳层传入实际回调。 <!-- pr-agent-dedup: 5c1093080900 --> <!-- pr-agent-key-issue-location: 256791003a90 -->
activitySlot: @Composable () -> Unit = { DefaultActivitySlot() },
) {
@@ -133,14 +134,6 @@ fun MainAppShell(
}
}
@Composable
private fun DefaultDevicesSlot() {
SlotPlaceholder(
title = stringResource(R.string.devices_placeholder_title),
description = stringResource(R.string.devices_placeholder_description),
)
}
@Composable
private fun DefaultScenesSlot() {
SlotPlaceholder(
@@ -42,4 +42,14 @@
<string name="scenes_placeholder_description">情景动作与执行插槽(由 tzh 模块实现)。</string>
<string name="activity_placeholder_title">活动记录</string>
<string name="activity_placeholder_description">未记录任何事件。</string>
<!-- 设备列表 -->
<string name="device_list_title">设备列表</string>
<string name="device_list_description">选择需要控制或查看状态的 ABox 终端设备。</string>
<string name="device_socket_title">智能插座</string>
<string name="device_socket_description">进入智能插座相关功能。</string>
<string name="device_temperature_humidity_title">温湿度传感器</string>
<string name="device_temperature_humidity_description">进入温湿度状态相关功能。</string>
<string name="device_infrared_title">红外控制器</string>
<string name="device_infrared_description">进入红外控制器相关功能。</string>
</resources>
@@ -42,4 +42,14 @@
<string name="scenes_placeholder_description">Scene actions and execution slot for tzh.</string>
<string name="activity_placeholder_title">Activity Log</string>
<string name="activity_placeholder_description">No recorded events yet.</string>
<!-- Device list -->
<string name="device_list_title">Device List</string>
<string name="device_list_description">Select an ABox terminal device to control or check status.</string>
<string name="device_socket_title">Smart Socket</string>
<string name="device_socket_description">Access smart socket features.</string>
<string name="device_temperature_humidity_title">Temperature &amp; Humidity Sensor</string>
<string name="device_temperature_humidity_description">View temperature and humidity status.</string>
<string name="device_infrared_title">Infrared Controller</string>
<string name="device_infrared_description">Access infrared controller features.</string>
</resources>