Update Wear Scaffold usage to be more consistent (#3562)

* Update TimeText to only show at the top of the screen

* Add Scaffold with PositionIndicator and TimeText where missing
This commit is contained in:
Joris Pelgröm 2023-06-03 02:45:06 +02:00 committed by GitHub
parent 2ff492a1c2
commit 8dac1627f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 305 additions and 253 deletions

View File

@ -44,7 +44,7 @@ fun ConversationResultView(
PositionIndicator(scalingLazyListState = scrollState)
}
},
timeText = { TimeText(visible = !scrollState.isScrollInProgress) }
timeText = { TimeText(scalingLazyListState = scrollState) }
) {
ScalingLazyColumn(
state = scrollState,

View File

@ -22,10 +22,13 @@ import androidx.compose.ui.unit.dp
import androidx.wear.compose.material.Icon
import androidx.wear.compose.material.InlineSlider
import androidx.wear.compose.material.InlineSliderDefaults
import androidx.wear.compose.material.PositionIndicator
import androidx.wear.compose.material.Scaffold
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.ToggleButton
import androidx.wear.compose.material.ToggleButtonDefaults
import androidx.wear.compose.material.ToggleChipDefaults
import androidx.wear.compose.material.rememberScalingLazyListState
import com.mikepenz.iconics.compose.Image
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import io.homeassistant.companion.android.common.R
@ -60,106 +63,116 @@ fun DetailsPanelView(
) {
val haptic = LocalHapticFeedback.current
val context = LocalContext.current
val scalingLazyListState = rememberScalingLazyListState()
WearAppTheme {
ThemeLazyColumn {
val attributes = entity.attributes as Map<*, *>
Scaffold(
positionIndicator = {
if (scalingLazyListState.isScrollInProgress) {
PositionIndicator(scalingLazyListState = scalingLazyListState)
}
},
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
) {
ThemeLazyColumn(state = scalingLazyListState) {
val attributes = entity.attributes as Map<*, *>
item {
Row(
verticalAlignment = Alignment.CenterVertically
) {
val friendlyName = attributes["friendly_name"].toString()
Text(friendlyName)
item {
Row(
verticalAlignment = Alignment.CenterVertically
) {
val friendlyName = attributes["friendly_name"].toString()
Text(friendlyName)
if (entity.domain in HomePresenterImpl.toggleDomains) {
val isChecked = entity.state in listOf("on", "locked", "open", "opening")
ToggleButton(
checked = isChecked,
onCheckedChange = {
onEntityToggled(entity.entityId, entity.state)
onEntityClickedFeedback(
isToastEnabled,
isHapticEnabled,
context,
friendlyName,
haptic
if (entity.domain in HomePresenterImpl.toggleDomains) {
val isChecked = entity.state in listOf("on", "locked", "open", "opening")
ToggleButton(
checked = isChecked,
onCheckedChange = {
onEntityToggled(entity.entityId, entity.state)
onEntityClickedFeedback(
isToastEnabled,
isHapticEnabled,
context,
friendlyName,
haptic
)
},
modifier = Modifier
.padding(start = 16.dp)
.size(ToggleButtonDefaults.SmallToggleButtonSize)
) {
Icon(
imageVector = ToggleChipDefaults.switchIcon(isChecked),
contentDescription = if (isChecked) {
stringResource(R.string.enabled)
} else {
stringResource(R.string.disabled)
}
)
},
modifier = Modifier
.padding(start = 16.dp)
.size(ToggleButtonDefaults.SmallToggleButtonSize)
) {
Icon(
imageVector = ToggleChipDefaults.switchIcon(isChecked),
contentDescription = if (isChecked) {
stringResource(R.string.enabled)
} else {
stringResource(R.string.disabled)
}
)
}
}
}
}
}
if (entity.domain == "fan") {
if (entity.supportsFanSetSpeed()) {
item {
FanSpeedSlider(entity, onFanSpeedChanged, isToastEnabled, isHapticEnabled)
if (entity.domain == "fan") {
if (entity.supportsFanSetSpeed()) {
item {
FanSpeedSlider(entity, onFanSpeedChanged, isToastEnabled, isHapticEnabled)
}
}
}
}
if (entity.domain == "light") {
if (entity.supportsLightBrightness()) {
item {
BrightnessSlider(entity, onBrightnessChanged, isToastEnabled, isHapticEnabled)
if (entity.domain == "light") {
if (entity.supportsLightBrightness()) {
item {
BrightnessSlider(entity, onBrightnessChanged, isToastEnabled, isHapticEnabled)
}
}
if (entity.supportsLightColorTemperature() && attributes["color_mode"] == EntityExt.LIGHT_MODE_COLOR_TEMP) {
item {
ColorTempSlider(attributes, onColorTempChanged, isToastEnabled, isHapticEnabled)
}
}
}
if (entity.supportsLightColorTemperature() && attributes["color_mode"] == EntityExt.LIGHT_MODE_COLOR_TEMP) {
item {
ColorTempSlider(attributes, onColorTempChanged, isToastEnabled, isHapticEnabled)
}
item {
ListHeader(R.string.details)
}
item {
Text(
stringResource(R.string.state_name, entity.state),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp)
)
}
item {
val lastChanged = DateFormat.getDateTimeInstance().format(entity.lastChanged.time)
Text(
stringResource(R.string.last_changed, lastChanged),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp)
)
}
item {
val lastUpdated = DateFormat.getDateTimeInstance().format(entity.lastUpdated.time)
Text(
stringResource(R.string.last_updated, lastUpdated),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp)
)
}
item {
Text(
stringResource(R.string.entity_id_name, entity.entityId),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp)
)
}
}
item {
ListHeader(R.string.details)
}
item {
Text(
stringResource(R.string.state_name, entity.state),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp)
)
}
item {
val lastChanged = DateFormat.getDateTimeInstance().format(entity.lastChanged.time)
Text(
stringResource(R.string.last_changed, lastChanged),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp)
)
}
item {
val lastUpdated = DateFormat.getDateTimeInstance().format(entity.lastUpdated.time)
Text(
stringResource(R.string.last_updated, lastUpdated),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp)
)
}
item {
Text(
stringResource(R.string.entity_id_name, entity.entityId),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp)
)
}
}
}

View File

@ -8,8 +8,11 @@ import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import androidx.wear.compose.material.Chip
import androidx.wear.compose.material.ChipDefaults
import androidx.wear.compose.material.PositionIndicator
import androidx.wear.compose.material.Scaffold
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.items
import androidx.wear.compose.material.rememberScalingLazyListState
import io.homeassistant.companion.android.common.data.integration.Entity
import io.homeassistant.companion.android.theme.WearAppTheme
import io.homeassistant.companion.android.util.playPreviewEntityScene1
@ -35,47 +38,57 @@ fun EntityViewList(
) {
// Remember expanded state of each header
val expandedStates = rememberExpandedStates(entityLists.keys.map { it.hashCode() })
val scalingLazyListState = rememberScalingLazyListState()
WearAppTheme {
ThemeLazyColumn {
for (header in entityListsOrder) {
val entities = entityLists[header].orEmpty()
if (entities.isNotEmpty()) {
item {
if (entityLists.size > 1) {
ExpandableListHeader(
string = header,
key = header.hashCode(),
expandedStates = expandedStates
)
} else {
ListHeader(header)
}
}
if (expandedStates[header.hashCode()]!!) {
val filtered = entities.filter { entityListFilter(it) }
items(filtered, key = { it.entityId }) { entity ->
EntityUi(
entity,
onEntityClicked,
isHapticEnabled,
isToastEnabled
) { entityId -> onEntityLongClicked(entityId) }
Scaffold(
positionIndicator = {
if (scalingLazyListState.isScrollInProgress) {
PositionIndicator(scalingLazyListState = scalingLazyListState)
}
},
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
) {
ThemeLazyColumn(state = scalingLazyListState) {
for (header in entityListsOrder) {
val entities = entityLists[header].orEmpty()
if (entities.isNotEmpty()) {
item {
if (entityLists.size > 1) {
ExpandableListHeader(
string = header,
key = header.hashCode(),
expandedStates = expandedStates
)
} else {
ListHeader(header)
}
}
if (expandedStates[header.hashCode()]!!) {
val filtered = entities.filter { entityListFilter(it) }
items(filtered, key = { it.entityId }) { entity ->
EntityUi(
entity,
onEntityClicked,
isHapticEnabled,
isToastEnabled
) { entityId -> onEntityLongClicked(entityId) }
}
if (filtered.isEmpty()) {
item {
Column {
Chip(
label = {
Text(
text = stringResource(commonR.string.loading_entities),
textAlign = TextAlign.Center
)
},
onClick = { /* No op */ },
colors = ChipDefaults.primaryChipColors()
)
if (filtered.isEmpty()) {
item {
Column {
Chip(
label = {
Text(
text = stringResource(commonR.string.loading_entities),
textAlign = TextAlign.Center
)
},
onClick = { /* No op */ },
colors = ChipDefaults.primaryChipColors()
)
}
}
}
}

View File

@ -72,7 +72,7 @@ fun MainView(
PositionIndicator(scalingLazyListState = scalingLazyListState)
}
},
timeText = { TimeText(!scalingLazyListState.isScrollInProgress) }
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
) {
ThemeLazyColumn(
state = scalingLazyListState

View File

@ -40,7 +40,7 @@ fun SensorManagerUi(
PositionIndicator(scalingLazyListState = scalingLazyListState)
}
},
timeText = { TimeText(!scalingLazyListState.isScrollInProgress) }
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
) {
ThemeLazyColumn(
state = scalingLazyListState

View File

@ -36,7 +36,7 @@ fun SensorsView(
PositionIndicator(scalingLazyListState = scalingLazyListState)
}
},
timeText = { TimeText(!scalingLazyListState.isScrollInProgress) }
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
) {
val sensorManagers = getSensorManagers()
ThemeLazyColumn(

View File

@ -47,7 +47,7 @@ fun SetFavoritesView(
PositionIndicator(scalingLazyListState = scalingLazyListState)
}
},
timeText = { TimeText(!scalingLazyListState.isScrollInProgress) }
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
) {
ThemeLazyColumn(
state = scalingLazyListState

View File

@ -17,9 +17,12 @@ import androidx.wear.compose.material.ButtonDefaults
import androidx.wear.compose.material.Chip
import androidx.wear.compose.material.ChipDefaults
import androidx.wear.compose.material.Icon
import androidx.wear.compose.material.PositionIndicator
import androidx.wear.compose.material.Scaffold
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.ToggleChip
import androidx.wear.compose.material.ToggleChipDefaults
import androidx.wear.compose.material.rememberScalingLazyListState
import com.mikepenz.iconics.compose.Image
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import io.homeassistant.companion.android.data.SimplifiedEntity
@ -38,88 +41,98 @@ fun SetTileShortcutsView(
isShowShortcutTextEnabled: Boolean,
onShowShortcutTextEnabled: (Boolean) -> Unit
) {
val scalingLazyListState = rememberScalingLazyListState()
WearAppTheme {
ThemeLazyColumn {
item {
ListHeader(id = commonR.string.shortcuts_tile)
}
item {
ToggleChip(
modifier = Modifier.fillMaxWidth(),
checked = isShowShortcutTextEnabled,
onCheckedChange = { onShowShortcutTextEnabled(it) },
label = {
Text(stringResource(commonR.string.shortcuts_tile_text_setting))
},
appIcon = {
Image(
asset =
if (isShowShortcutTextEnabled) {
CommunityMaterial.Icon.cmd_alphabetical
} else {
CommunityMaterial.Icon.cmd_alphabetical_off
},
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
)
},
toggleControl = {
Icon(
imageVector = ToggleChipDefaults.checkboxIcon(isShowShortcutTextEnabled),
contentDescription = if (isShowShortcutTextEnabled) {
stringResource(commonR.string.show)
} else {
stringResource(commonR.string.hide)
}
)
}
)
}
item {
ListHeader(id = commonR.string.shortcuts_choose)
}
items(shortcutEntities.size) { index ->
val iconBitmap = getIcon(
shortcutEntities[index].icon,
shortcutEntities[index].domain,
LocalContext.current
)
Chip(
modifier = Modifier
.fillMaxWidth(),
icon = {
Image(
iconBitmap ?: CommunityMaterial.Icon.cmd_bookmark,
colorFilter = ColorFilter.tint(Color.White)
)
},
label = {
Text(
text = stringResource(commonR.string.shortcut_n, index + 1)
)
},
secondaryLabel = {
Text(
text = shortcutEntities[index].friendlyName,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
},
onClick = { onShortcutEntitySelectionChange(index) },
colors = ChipDefaults.secondaryChipColors()
)
}
if (shortcutEntities.size < 7) {
Scaffold(
positionIndicator = {
if (scalingLazyListState.isScrollInProgress) {
PositionIndicator(scalingLazyListState = scalingLazyListState)
}
},
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
) {
ThemeLazyColumn(state = scalingLazyListState) {
item {
Button(
modifier = Modifier.padding(top = 16.dp),
onClick = { onShortcutEntitySelectionChange(shortcutEntities.size) },
colors = ButtonDefaults.primaryButtonColors()
) {
Image(
CommunityMaterial.Icon3.cmd_plus_thick
)
ListHeader(id = commonR.string.shortcuts_tile)
}
item {
ToggleChip(
modifier = Modifier.fillMaxWidth(),
checked = isShowShortcutTextEnabled,
onCheckedChange = { onShowShortcutTextEnabled(it) },
label = {
Text(stringResource(commonR.string.shortcuts_tile_text_setting))
},
appIcon = {
Image(
asset =
if (isShowShortcutTextEnabled) {
CommunityMaterial.Icon.cmd_alphabetical
} else {
CommunityMaterial.Icon.cmd_alphabetical_off
},
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
)
},
toggleControl = {
Icon(
imageVector = ToggleChipDefaults.checkboxIcon(isShowShortcutTextEnabled),
contentDescription = if (isShowShortcutTextEnabled) {
stringResource(commonR.string.show)
} else {
stringResource(commonR.string.hide)
}
)
}
)
}
item {
ListHeader(id = commonR.string.shortcuts_choose)
}
items(shortcutEntities.size) { index ->
val iconBitmap = getIcon(
shortcutEntities[index].icon,
shortcutEntities[index].domain,
LocalContext.current
)
Chip(
modifier = Modifier
.fillMaxWidth(),
icon = {
Image(
iconBitmap ?: CommunityMaterial.Icon.cmd_bookmark,
colorFilter = ColorFilter.tint(Color.White)
)
},
label = {
Text(
text = stringResource(commonR.string.shortcut_n, index + 1)
)
},
secondaryLabel = {
Text(
text = shortcutEntities[index].friendlyName,
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
},
onClick = { onShortcutEntitySelectionChange(index) },
colors = ChipDefaults.secondaryChipColors()
)
}
if (shortcutEntities.size < 7) {
item {
Button(
modifier = Modifier.padding(top = 16.dp),
onClick = { onShortcutEntitySelectionChange(shortcutEntities.size) },
colors = ButtonDefaults.primaryButtonColors()
) {
Image(
CommunityMaterial.Icon3.cmd_plus_thick
)
}
}
}
}

View File

@ -84,7 +84,7 @@ fun SettingsView(
PositionIndicator(scalingLazyListState = scalingLazyListState)
}
},
timeText = { TimeText(!scalingLazyListState.isScrollInProgress) }
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
) {
ThemeLazyColumn(
state = scalingLazyListState

View File

@ -12,10 +12,14 @@ import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import androidx.wear.compose.material.Chip
import androidx.wear.compose.material.ChipDefaults
import androidx.wear.compose.material.PositionIndicator
import androidx.wear.compose.material.Scaffold
import androidx.wear.compose.material.Text
import androidx.wear.compose.material.rememberScalingLazyListState
import com.mikepenz.iconics.compose.Image
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import io.homeassistant.companion.android.common.R
import io.homeassistant.companion.android.theme.WearAppTheme
import io.homeassistant.companion.android.theme.wearColorPalette
import io.homeassistant.companion.android.util.IntervalToString
import io.homeassistant.companion.android.views.ListHeader
@ -27,41 +31,53 @@ fun TemplateTileSettingsView(
refreshInterval: Int,
onClickRefreshInterval: () -> Unit
) {
ThemeLazyColumn {
item {
ListHeader(id = R.string.template_tile)
}
item {
Chip(
modifier = Modifier
.fillMaxWidth(),
icon = {
Image(
asset = CommunityMaterial.Icon3.cmd_timer_cog,
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
val scalingLazyListState = rememberScalingLazyListState()
WearAppTheme {
Scaffold(
positionIndicator = {
if (scalingLazyListState.isScrollInProgress) {
PositionIndicator(scalingLazyListState = scalingLazyListState)
}
},
timeText = { TimeText(scalingLazyListState = scalingLazyListState) }
) {
ThemeLazyColumn(state = scalingLazyListState) {
item {
ListHeader(id = R.string.template_tile)
}
item {
Chip(
modifier = Modifier
.fillMaxWidth(),
icon = {
Image(
asset = CommunityMaterial.Icon3.cmd_timer_cog,
colorFilter = ColorFilter.tint(wearColorPalette.onSurface)
)
},
colors = ChipDefaults.secondaryChipColors(),
label = {
Text(
text = stringResource(id = R.string.refresh_interval)
)
},
secondaryLabel = { Text(IntervalToString(LocalContext.current, refreshInterval)) },
onClick = onClickRefreshInterval
)
},
colors = ChipDefaults.secondaryChipColors(),
label = {
}
item {
ListHeader(R.string.template_tile_content)
}
item {
Text(stringResource(R.string.template_tile_change_message))
}
item {
Text(
text = stringResource(id = R.string.refresh_interval)
templateContent,
color = Color.DarkGray
)
},
secondaryLabel = { Text(IntervalToString(LocalContext.current, refreshInterval)) },
onClick = onClickRefreshInterval
)
}
item {
ListHeader(R.string.template_tile_content)
}
item {
Text(stringResource(R.string.template_tile_change_message))
}
item {
Text(
templateContent,
color = Color.DarkGray
)
}
}
}
}
}

View File

@ -1,31 +1,28 @@
package io.homeassistant.companion.android.home.views
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview
import androidx.wear.compose.material.ScalingLazyListState
import androidx.wear.compose.material.TimeText
import androidx.wear.compose.material.rememberScalingLazyListState
import androidx.wear.compose.material.scrollAway
@Composable
fun TimeText(
visible: Boolean
scalingLazyListState: ScalingLazyListState
) {
AnimatedVisibility(
visible = visible,
enter = slideInVertically(),
exit = slideOutVertically()
) {
TimeText()
}
TimeText(
modifier = Modifier.scrollAway(scrollState = scalingLazyListState)
)
}
@Preview(device = Devices.WEAR_OS_LARGE_ROUND)
@Composable
private fun PreviewTimeText() {
CompositionLocalProvider {
TimeText(visible = true)
TimeText(scalingLazyListState = rememberScalingLazyListState())
}
}

View File

@ -39,7 +39,7 @@ fun PhoneInstallView(
PositionIndicator(scalingLazyListState = scrollState)
}
},
timeText = { TimeText(visible = !scrollState.isScrollInProgress) }
timeText = { TimeText(scalingLazyListState = scrollState) }
) {
Box(modifier = Modifier.background(MaterialTheme.colors.background)) {
ThemeLazyColumn(state = scrollState) {