1

我有一个包含 Slider 的列表,问题是当我滚动检测到点击事件的滑块并更改它时,请参阅附加的 gif

见附件 gif

例外的行为是当用户滚动滑块时,不会在用户点击滑块时改变。

如何避免在滚动时更改滑块?

相关代码:

    @Composable
fun TodoScreen(
    items: List<TodoItem>,
    currentlyEditing: TodoItem?,
    onAddItem: (TodoItem) -> Unit,
    onRemoveItem: (TodoItem) -> Unit,
    onStartEdit: (TodoItem) -> Unit,
    onEditItemChange: (TodoItem) -> Unit,
    onEditDone: () -> Unit,
    onPositionChanged: (TodoItem, Float) -> Unit
) {
    Column {
        val enableTopSection = currentlyEditing == null
        TodoItemInputBackground(elevate = enableTopSection) {
            if (enableTopSection) {
                TodoItemEntryInput(onAddItem)
            } else {
                Text(
                    text = "Editing item",
                    style = MaterialTheme.typography.h6,
                    textAlign = TextAlign.Center,
                    modifier = Modifier
                        .align(Alignment.CenterVertically)
                        .padding(16.dp)
                        .fillMaxWidth()
                )
            }
        }

        LazyColumn(
            modifier = Modifier.weight(1f),
            contentPadding = PaddingValues(top = 8.dp)
        ) {
            items(items = items) { todo ->
                if (currentlyEditing?.id == todo.id) {
                    Log.d("ListTodo", "task: ${todo.task}")
                    TodoItemInlineEditor(
                        item = currentlyEditing,
                        onEditItemChange = onEditItemChange,
                        onEditDone = onEditDone,
                        onRemoveItem = { onRemoveItem(todo) }
                    )
                } else {
                    TodoRow(
                        todo = todo,
                        onItemClicked = { onStartEdit(it) },
                        modifier = Modifier.fillParentMaxWidth(),
                        position = todo.position,
                        onPositionChanged = onPositionChanged
                    )
                }
            }
        }

        // For quick testing, a random item generator button
        Button(
            onClick = { onAddItem(generateRandomTodoItem()) },
            modifier = Modifier
                .padding(16.dp)
                .fillMaxWidth(),
        ) {
            Text("Add random item")
        }
    }
}

@Composable
fun TodoRow(
    todo: TodoItem,
    onItemClicked: (TodoItem) -> Unit,
    modifier: Modifier = Modifier,
    iconAlpha: Float = remember(todo.id) { randomTint() },
    position: Float,
    onPositionChanged: (TodoItem, Float) -> Unit
) {
    Column() {
        Row(
            modifier
                .clickable { onItemClicked(todo) }
                .padding(horizontal = 16.dp, vertical = 8.dp),
            horizontalArrangement = Arrangement.SpaceBetween
        ) {
            Text(todo.task)
            Icon(
                imageVector = todo.icon.imageVector,
                tint = LocalContentColor.current.copy(alpha = iconAlpha),
                contentDescription = stringResource(id = todo.icon.contentDescription)
            )
        }
        Slider(value = position, onValueChange = { onPositionChanged(todo.copy(position = it), it) })
    }
}
4

1 回答 1

0

一个非常简单且开箱即用的解决方案可以rememberLazyListState()用于检查是否isScrollInProgressfalse,然后才允许TodoRow修改器.clickable和 Slider onValueChangelambda 中的代码运行。

像这样的东西:

@Composable
fun Content() {
    //This instance of rememberLazyListState
    val listState = rememberLazyListState()

    LazyColumn(
        state = listState, // Go here!
        contentPadding = PaddingValues(top = 8.dp)
    ) {
        items(listOfItems) { item ->
            TodoRow(listState = listState, todo = item) {
                Log.d("TAG", "onItemClicked")
            }
        }
    }
}

然后在 TodoRow 中:

@Composable
fun TodoRow(
    listState: LazyListState,
    todo: String,
    onItemClicked: (String) -> Unit
) {
    Column {
        
        Row(Modifier
                .clickable {
                    if (!listState.isScrollInProgress) { //This line
                        onItemClicked(todo)
                    }
                }
        ) {
            //Your Code...
        }
        
        Slider(
            value = someRememberableValue,
            onValueChange = {
                if (!listState.isScrollInProgress) {  //This line
                    //Your Code...
                }
            }
        )
    }
}

此外,如果您愿意,您可以仅从isScrollInProgress状态中提取布尔值并将其仅传递给TodoRow.

这应该可行,但可能是第一个接触点将被注册。(当列表实际上没有滚动时)。

如果这还不够,我会考虑收听并覆盖屏幕触摸和点击事件。

https://developer.android.com/jetpack/compose/gestures

于 2022-02-16T21:17:00.800 回答