[英]Jetpack Compose - how to make SwipeToDismiss work on LazyRow?
我看到很多关于 SwipeToDismiss 在 LazyColumn 上工作的例子,但我没有看到一个在 LazyRow 上实现它的例子。 这是我目前的实施 -
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun DashboardDataState(dashboardCardModels: List<DashboardCardModel>) {
Column(
modifier = Modifier
.fillMaxSize()
.background(
brush = Brush.verticalGradient(
colors = listOf(
backgroundStartColor,
backgroundEndColor
)
)
),
verticalArrangement = Arrangement.Center
) {
LazyRow(modifier = Modifier.wrapContentSize()) {
items(dashboardCardModels) { model ->
val dismissState = rememberDismissState()
when {
dismissState.isDismissed(DismissDirection.EndToStart) ->{
}
dismissState.isDismissed(DismissDirection.StartToEnd) ->{
}
}
SwipeToDismiss(
state = rememberDismissState(),
background = {
val color by animateColorAsState(
when (dismissState.targetValue) {
DismissValue.Default -> Color.White
DismissValue.DismissedToEnd -> Color.Blue
DismissValue.DismissedToStart -> Color.Red
}
)
val alignment = Alignment.CenterEnd
val icon = Icons.Default.Delete
val scale by animateFloatAsState(
if (dismissState.targetValue == DismissValue.Default) 0.75f else 1f
)
Box(
Modifier
.fillMaxSize()
.background(color)
.padding(horizontal = Dp(20f)),
contentAlignment = alignment
) {
Icon(
icon,
contentDescription = "Delete Icon",
modifier = Modifier.scale(scale)
)
}
},
dismissContent = {
DashboardCard(model = model)
}
)
}
}
}
}
发生的情况是我能够水平滑动 LazyRow,但显然我想垂直滑动它。 我怎样才能实现这种行为?
深入研究SwipeToDismiss
代码并了解它的行为,我做了一些简单的修改,将height
变量更改为width
,将滑动方向更改为Orientation.Vertical
并将dismissContent
变量在 y 轴而不是 x 轴上的偏移量更改为 go。 我将修改后的可组合项命名为SwipeToDismissVertical
,它运行良好
@Composable
@ExperimentalMaterialApi
fun SwipeToDismissVertical(
state: DismissState,
modifier: Modifier = Modifier,
directions: Set<DismissDirection> = setOf(DismissDirection.EndToStart, DismissDirection.StartToEnd),
dismissThresholds: (DismissDirection) -> ThresholdConfig = {
FixedThreshold(DISMISS_THRESHOLD)
},
background: @Composable RowScope.() -> Unit,
dismissContent: @Composable RowScope.() -> Unit
) = BoxWithConstraints(modifier) {
val width = constraints.maxWidth.toFloat()
val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
val anchors = mutableMapOf(0f to DismissValue.Default)
if (DismissDirection.StartToEnd in directions) anchors += width to DismissValue.DismissedToEnd
if (DismissDirection.EndToStart in directions) anchors += -width to DismissValue.DismissedToStart
val thresholds = { from: DismissValue, to: DismissValue ->
dismissThresholds(getDismissDirection(from, to)!!)
}
val minFactor =
if (DismissDirection.EndToStart in directions) SwipeableDefaults.StandardResistanceFactor else SwipeableDefaults.StiffResistanceFactor
val maxFactor =
if (DismissDirection.StartToEnd in directions) SwipeableDefaults.StandardResistanceFactor else SwipeableDefaults.StiffResistanceFactor
Box(
Modifier.swipeable(
state = state,
anchors = anchors,
thresholds = thresholds,
orientation = Orientation.Vertical,
enabled = state.currentValue == DismissValue.Default,
reverseDirection = isRtl,
resistance = ResistanceConfig(
basis = width,
factorAtMin = minFactor,
factorAtMax = maxFactor
)
)
) {
Row(
content = background,
modifier = Modifier.matchParentSize()
)
Row(
content = dismissContent,
modifier = Modifier.offset { IntOffset(0, state.offset.value.roundToInt(), ) }
)
}
}
private val DISMISS_THRESHOLD = 56.dp
private fun getDismissDirection(from: DismissValue, to: DismissValue): DismissDirection? {
return when {
// settled at the default state
from == to && from == DismissValue.Default -> null
// has been dismissed to the end
from == to && from == DismissValue.DismissedToEnd -> DismissDirection.StartToEnd
// has been dismissed to the start
from == to && from == DismissValue.DismissedToStart -> DismissDirection.EndToStart
// is currently being dismissed to the end
from == DismissValue.Default && to == DismissValue.DismissedToEnd -> DismissDirection.StartToEnd
// is currently being dismissed to the start
from == DismissValue.Default && to == DismissValue.DismissedToStart -> DismissDirection.EndToStart
// has been dismissed to the end but is now animated back to default
from == DismissValue.DismissedToEnd && to == DismissValue.Default -> DismissDirection.StartToEnd
// has been dismissed to the start but is now animated back to default
from == DismissValue.DismissedToStart && to == DismissValue.Default -> DismissDirection.EndToStart
else -> null
}
}
用法与以前完全相同,但现在我使用我的新可组合项而不是材料组合项 -
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun DashboardDataState(dashboardCardModels: List<DashboardCardModel>) {
Column(
modifier = Modifier
.fillMaxSize()
.background(
brush = Brush.verticalGradient(
colors = listOf(
backgroundStartColor,
backgroundEndColor
)
)
),
verticalArrangement = Arrangement.Center
) {
LazyRow(modifier = Modifier.wrapContentSize()) {
items(dashboardCardModels) { model ->
val dismissState = rememberDismissState()
when {
dismissState.isDismissed(DismissDirection.EndToStart) ->{
}
dismissState.isDismissed(DismissDirection.StartToEnd) ->{
}
}
SwipeToDismissVertical( //Here is the new one
state = dismissState,
background = {
val color by animateColorAsState(
when (dismissState.targetValue) {
DismissValue.Default -> Color.Transparent
DismissValue.DismissedToEnd -> Color.Blue
DismissValue.DismissedToStart -> Color.Red
}
)
val alignment = Alignment.CenterEnd
val icon = Icons.Default.Delete
val scale by animateFloatAsState(
if (dismissState.targetValue == DismissValue.Default) 0.75f else 1f
)
Box(
Modifier
.fillMaxSize()
.background(color)
.padding(horizontal = Dp(20f)),
contentAlignment = alignment
) {
Icon(
icon,
contentDescription = "Delete Icon",
modifier = Modifier.scale(scale)
)
}
},
dismissContent = {
DashboardCard(model = model)
}
)
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.