首页 > 解决方案 > Jetpack Compose - LazyColumn 进行无限次数的重组

问题描述

我想使用 显示项目列表LazyColumn。我编写了所需的代码,但是当我运行应用程序时,我发现 UI 非常滞后。我放了一些Logs来找出问题可能出在哪里,我发现LazyColumn无限地重新组合了这些项目。我用带有可滚动修饰符的替换了LazyColumnColumn在这种情况下问题就消失了。但我不知道为什么LazyColumn会这样。

清单是这样的:

var rides = mutableStateListOf<Ride>(Ride(...), Ride(...))

一个列表项是这样的:

@Stable
@Entity(tableName = "ride_table")
data class Ride(
    var img: Bitmap? = null,
    var path: List<List<LatLng>>? = null,
    var cities: List<String>? = null,
    var timeStarted: Long = 0L,
    var timeEnded: Long = 0L,
    var avgSpeedInKmh: Float = 0f,
    var maxSpeedInKmh: Float = 0f,
    var distanceInMeters: Float = 0f,
    var totalTimeInSeconds: Long = 0L,
    @PrimaryKey(autoGenerate = true)
    var id: Long = 0L
) {
    override fun equals(other: Any?): Boolean {
        if(other == null)
            return false
        if(other is Ride) {
            return id == other.id
        } else {
            return false
        }
    }
}

可组合的列表:

@Composable
fun Rides(rides: List<Ride>) {
    Log.d("RECOMPOSE", "1")
    LazyColumn {
        items(rides) { ride ->
            Log.d("RECOMPOSE", "2")
            RideDetails(ride)
        }
    }
    /*Column(modifier = Modifier.verticalScroll(rememberScrollState())) {
        rides.forEach { ride ->
            Log.d("RECOMPOSE", "2")
            RideDetails(ride)
        }
    }*/
}

骑行详情:

@Composable
fun RideDetails(ride: Ride) {
    Log.d("RECOMPOSE", "3`")
    Text(text = "ride ${ride}")
}

Log Recompose 2在 的情况下被称为不间断LazyColumn。如果我切换到Column这不会发生并且Log呼叫次数是预期的。我在做什么错使用LazyColumn

更新(以下内容在位于的Column内部被调用)setContentonCreateView

Column {

    val cities = rideViewModel.cities
    val filterCities = rideViewModel.filterCities
        
    val rides = rideViewModel.rides

    TopBar {
        ...
    }

    Chips(cities, filterCities)

    Log.d("RECOMPOSE", "RECOMPOSE INSIDE SCREEN")

    Rides(rides)
}

标签: androidandroid-jetpack-composeandroid-jetpack

解决方案


我刚刚在Thinking in Compose文章中稍微修改了代码时遇到了同样的问题。在我看来,这是@Philip Dukhov 要求的最小可重复性

在这种情况下,它通过了一个包含 30 项的小清单,但计数器无休止地上升。LazyColumn 仅显示通过的 30 个项目。

我将非常感谢您的解释。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            SimpleAnimationsTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    var testList = listOf<String>()
                    for(i in 1..30) testList += "Test #$i"
                    ListWithoutBug(myList = testList)
                }
            }
        }
    }
}

@Composable
fun ListWithoutBug(myList: List<String>) { // apparently with bug
    val items = remember { mutableStateOf<Int>(0) }

    Row(horizontalArrangement = Arrangement.SpaceBetween) {
        LazyColumn{
            items(myList) { item ->
                Text("Item: $item")
                items.value++
            }
        }
        Text("Count: ${items.value}")
    }
}

截屏


推荐阅读