我正在 jetpack compose 中的嵌套列上工作。我有一个列表,其中包含来自服务器的大量数据。我在布局检查器中进行了检查,我发现每当我的项目添加到列表中时,它都会重新组合并增加计数。所以我的疑问是,如果我在列表中一一添加 100 个项目,那么我的Nested Column
将100 times recompose
?如果没有,有人可以帮我吗?
ListViewComposableActivity.kt
class ListViewComposableActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AppBarScaffold(
displayHomeAsUpEnabled = true,
titleId = R.string.activity
) {
ListViewItemStateful()
}
}
}
}
ListView 项目有状态
@Composable
fun ListViewItemStateful(
viewModel: ListViewModel = koinViewModel(),
) {
ItemViewListStateless(
uiState = viewModel.uiState,
isEnable = viewModel.isEnable,
scanDeviceList = viewModel.scanResultList,
)
}
ItemViewList无状态
@Composable
fun ItemViewListStateless(
uiState: State,
isEnable: Boolean,
scanDeviceList: SnapshotStateList<ScanResults>,
) {
when (uiState) {
INITIAL,
FIRST -> {
ListContent(isEnable, scanDeviceList)
}
}
}
列表内容
@Composable
fun ListContent(isEnable: Boolean, scanDeviceList: SnapshotStateList<ScanResults>) {
AnimatedVisibility(true) {
Column(
modifier = Modifier
.padding(16.dp)
.fillMaxSize()
.verticalScroll(rememberScrollState()),
) {
if (isEnable) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
DeviceList(
scanDeviceList,
modifier = Modifier.align(Alignment.Start),
)
}
}
}
}
}
设备列表
@Composable
fun ColumnScope.DeviceList(
scanDeviceList: SnapshotStateList<ScanResults>,
modifier: Modifier = Modifier,
) {
Spacer(modifier = Modifier.height(32.dp))
AnimatedVisibility(
scanDeviceList.isNotEmpty(),
modifier = modifier
) {
Column {
Text(text = "Device List")
scanDeviceList.forEachIndexed { index, scanResults ->
Text(text = scanResults.device.name)
}
}
}
}
ListViewModel.kt
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.viewModelScope
import com.abc.app.common.BaseViewModel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class ListViewModel : BaseViewModel() {
val scanResultList by lazy { mutableStateListOf<ScanResults>() }
var isEnable by mutableStateOf(false)
private set
var uiState by mutableStateOf<State>(State.INITIAL)
private set
init {
viewModelScope.launch {
(0..10).forEach {
delay(2000)
scanResultList.add(ScanResults(Device("item $it")))
}
}
isEnable = true
uiState = State.FIRST
}
}
data class ScanResults(val device: Device)
data class Device(val name: String)
enum class State {
INITIAL,
FIRST
}
我在列表中添加了一些项目以在布局检查器中显示
![enter image description here](https://i.stack.imgur.com/NCTFG.png)
在上图中你可以看到DeviceList
是重构10次。
我签到了Jetpack Compose:调试重组大约 6:40 分钟,他尝试解决重组问题,并且跳过的重组计数很明显。那么为什么它在重组和跳过部分中显示我的组件树中的计数呢?非常感谢
UPDATE
当我改为@Thracian 回答时,它仍然重新组合跳过
![enter image description here](https://i.stack.imgur.com/8XADM.png)
@Composable
fun ColumnScope.DeviceList(
scanDeviceList:()-> SnapshotStateList<ScanResults>,
modifier: Modifier = Modifier,
) {
Spacer(modifier = Modifier.height(32.dp))
AnimatedVisibility(
scanDeviceList().isNotEmpty(),
modifier = modifier
) {
Column {
Text(text = "Device List")
scanDeviceList().forEachIndexed { index, scanResults ->
Item(scanResults.device)
}
}
}
}
@Composable
private fun Item(device: Device) {
Text(
modifier = Modifier.border(2.dp, getRandomColor()),
text = device.name
)
}
fun getRandomColor() = Color(
red = Random.nextInt(256),
green = Random.nextInt(256),
blue = Random.nextInt(256),
alpha = 255
)