And*_*lov 10 android android-scroll android-jetpack-compose android-jetpack-compose-lazy-column
我使用 Jetpack Compose UI 构建一个简单的 TODO 应用程序。这个想法是有一个可以选中或取消选中的任务列表,并且选中的任务应该位于列表的末尾。
一切工作正常,除了当我检查屏幕上的第一个可见项目时,它会随着滚动位置向下移动。
我相信这与 有关LazyListState
,有这样的功能:
/**
* When the user provided custom keys for the items we can try to detect when there were
* items added or removed before our current first visible item and keep this item
* as the first visible one even given that its index has been changed.
*/
internal fun updateScrollPositionIfTheFirstItemWasMoved(itemsProvider: LazyListItemsProvider) {
scrollPosition.updateScrollPositionIfTheFirstItemWasMoved(itemsProvider)
}
Run Code Online (Sandbox Code Playgroud)
所以我想禁用这种行为,但我没有找到方法。
下面是重现问题的简单代码和截屏视频。当我尝试检查“项目 0”、“项目 1”和“项目 4”时,此截屏视频中出现问题,但在检查“项目 7”和“项目 8”时,它按我预期的方式工作。
如果您选中或取消选中当前第一个可见项目的任何项目,不仅该项目位于整个列表中的第一个项目,其行为也相同。
class MainActivity : ComponentActivity() {
@OptIn(ExperimentalFoundationApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
val checkItems by remember { mutableStateOf(generate(20)) }
LazyColumn() {
items(
items = checkItems.sortedBy { it.checked.value },
key = { item -> item.id }
) { entry ->
Row(
modifier = Modifier.animateItemPlacement(),
verticalAlignment = Alignment.CenterVertically,
) {
Checkbox(
checked = entry.checked.value,
onCheckedChange = {
checkItems.find { it == entry }
?.apply { this.checked.value = !this.checked.value }
}
)
Text(text = entry.text)
}
}
}
}
}
}
}
}
data class CheckItem(val id: String, var checked: MutableState<Boolean> = mutableStateOf(false), var text: String = "")
fun generate(count: Int): List<CheckItem> =
(0..count).map { CheckItem(it.toString(), mutableStateOf(it % 2 == 0), "Item $it") }
Run Code Online (Sandbox Code Playgroud)
由于animateItemPlacement
惰性项目需要唯一的 ID/密钥才能获得动画,因此可能会牺牲第一个项目,因此key
使用其index
位置(无动画)设置其将防止出现此问题
itemsIndexed(
items = checkItems.sortedBy { it.checked.value },
key = { index, item -> if (index == 0) index else item.id }
) { index, entry ->
...
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1545 次 |
最近记录: |