feat: Improve visual feedback for reorderable lists
Enhances the visual experience when reordering items in both shopping list detail and shopping lists screens. - Implemented animated scaling and background color changes for items being dragged to provide clearer visual feedback. - Adjusted shadow behavior during dragging to be consistent across themes, specifically removing the shadow in dark theme for a cleaner look.
This commit is contained in:
@@ -33,6 +33,10 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.draw.shadow
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@@ -142,16 +146,25 @@ fun ShoppingListDetailScreen(
|
||||
state = lazyListState,
|
||||
) {
|
||||
items(filteredItems, { it.id }) { item ->
|
||||
ReorderableItem(reorderableLazyListState, key = item.id) { isDragging ->
|
||||
val elevation = if (isDragging) 8.dp else 0.dp
|
||||
ReorderableItem(reorderableLazyListState, key = item.id) { isDragging ->
|
||||
val elevation = animateDpAsState(if (isDragging) 0.dp else 0.dp, label = "elevation")
|
||||
val scale = animateFloatAsState(if (isDragging) 1.05f else 1.0f, label = "scale")
|
||||
val isSelected = item == selectedItem
|
||||
val backgroundColor = animateColorAsState(
|
||||
if (isDragging) MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.7f)
|
||||
else if (isSelected) MaterialTheme.colorScheme.surfaceVariant
|
||||
else Color.Transparent, label = "backgroundColor"
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.shadow(elevation)
|
||||
.background(if (isSelected) MaterialTheme.colorScheme.surfaceVariant else Color.Transparent)
|
||||
.clickable(interactionSource = remember { MutableInteractionSource() }, indication = null) {
|
||||
coroutineScope.launch {
|
||||
.graphicsLayer {
|
||||
scaleX = scale.value
|
||||
scaleY = scale.value
|
||||
}
|
||||
.shadow(elevation.value)
|
||||
.background(backgroundColor.value)
|
||||
.clickable(interactionSource = remember { MutableInteractionSource() }, indication = null) { coroutineScope.launch {
|
||||
viewModel.saveShoppingListItem(item.copy(isChecked = !item.isChecked))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package de.lxtools.noteshop.ui.shopping
|
||||
|
||||
import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -37,6 +41,9 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.shadow
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
@@ -107,7 +114,8 @@ fun ShoppingListsScreen(
|
||||
},
|
||||
modifier = Modifier
|
||||
.clickable { onListClick(listWithItems.shoppingList.id) },
|
||||
scope = this
|
||||
scope = this,
|
||||
isDragging = isDragging
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -149,18 +157,33 @@ fun ShoppingListsScreen(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Composable
|
||||
fun ShoppingListCard(
|
||||
listWithItems: ShoppingListWithItems,
|
||||
onEditList: (ShoppingListWithItems) -> Unit,
|
||||
onDeleteList: (ShoppingListWithItems) -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
scope: ReorderableCollectionItemScope
|
||||
scope: ReorderableCollectionItemScope,
|
||||
isDragging: Boolean
|
||||
) {
|
||||
val elevation = animateDpAsState(if (isDragging) 0.dp else 0.dp, label = "elevation")
|
||||
val scale = animateFloatAsState(if (isDragging) 1.05f else 1.0f, label = "scale")
|
||||
val backgroundColor = animateColorAsState(
|
||||
if (isDragging) MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.7f)
|
||||
else Color.Transparent, label = "backgroundColor"
|
||||
)
|
||||
Card(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 4.dp, horizontal = 16.dp)
|
||||
.graphicsLayer {
|
||||
scaleX = scale.value
|
||||
scaleY = scale.value
|
||||
}
|
||||
.shadow(elevation.value)
|
||||
.background(backgroundColor.value)
|
||||
) {
|
||||
Column(modifier = Modifier.padding(16.dp)) {
|
||||
Row(
|
||||
|
||||
Reference in New Issue
Block a user