我有一个关于Jetpack的问题,即显示包含ModelList
个项目的模型。添加新项目后,UI元素的顺序将变得不正确。
这是一个非常简单的CounterModel
,其中包含ModelList
的{{1}}:
ItemModel
该屏幕为每个@Model
data class CounterModel(
var counter: Int = 0,
var name: String = "",
val items: ModelList<ItemModel> = ModelList()
)
@Model
data class ItemModel(
var name: String
)
显示两张卡行:ItemModel
和RowA
。
创建此屏幕时,请使用以下RowB
进行初始化:
CounterModel
...按预期显示,像这样:
项目1 A行
项目1 B行
项目2 A行
项目2 B行
当我单击“添加”按钮以插入新的val model = CounterModel()
model.name="hi"
model.items.add(ItemModel("Item 1"))
model.items.add(ItemModel("Item 2"))
CounterModelScreen(model)
时,我只是希望看到
项目3 A行
项目3 B行
在底部。但是相反,顺序混乱了,我看到两个rowA然后两个rowB:
项目1 A行
项目1 B行
项目2 A行
项目3 A行
项目3 B行
项目2 B行
我不太了解这是怎么可能的。 UI代码非常简单:遍历ItemModel
并为每一个发出items
和RowA
:
RowB
使用Android Studio 4.0C6
这是完整的代码:
for (i in counterModel.items.indices) {
RowA(counterModel, i)
RowB(counterModel, i)
}
答案 0 :(得分:1)
我已经使用 compose-1.0.0-alpha07 进行了测试,并进行了一些更改以使代码适应更改后的API。一切都可以正常工作,因此我猜测是由于旧版本的compose代码看起来正确,并且在具有上述更改的最新版本中可以工作,因此某些东西已损坏。
我还修改了您的代码以使用docs中建议的状态,并添加了一个ViewModel,它将帮助您将视图与数据管理分离:
ViewModel
if __name__ == '__main__':
n = int(input())
arr = map(int, input().split())
print(sorted(list(set(arr)))[-2])
可组合视图已更新:
class CounterModelViewModel : ViewModel() {
private val myBaseModel = CounterModel().apply {
name = "hi"
items.add(ItemModel("Item 1"))
items.add(ItemModel("Item 2"))
}
private val _modelLiveData = MutableLiveData(myBaseModel)
val modelLiveData: LiveData<CounterModel> = _modelLiveData
fun addNewItem() {
val oldCounterModel = modelLiveData.value ?: CounterModel()
// Items is casted to a new MutableList because the new state won't be notified if the new
// counter model content is the same one as the old one. You can also change any other
// properties instead like the name or the counter
val newItemsList = oldCounterModel.items.toMutableList()
newItemsList.add(ItemModel("Item " + (newItemsList.size + 1)))
// Pass a new instance of CounterModel to the LiveData
val newCounterModel = oldCounterModel.copy(items = newItemsList)
_modelLiveData.value = newCounterModel
}
}
之前的代码是从另一个包含ViewModel实例的可组合函数中调用的,但是您可以将其更改为带有提到的ViewModel实例的活动或片段,这取决于您的偏好。
@Composable
fun CounterModelScreen(counterModel: CounterModel, onAddNewItem: () -> Unit) {
ScrollableColumn {
TopAppBar(title = {
Text(
text = "Counter Model"
)
})
CounterHeader(counterModel)
counterModel.items.forEachIndexed { index, item ->
RowA(counterModel, index)
RowB(counterModel, index)
}
Button(
onClick = onAddNewItem
) {
Text(text = "Add")
}
}
}
@Composable
fun CounterHeader(counterModel: CounterModel) {
Text(text = counterModel.name)
}
@Composable
fun RowA(counterModel: CounterModel, index: Int) {
Card(
backgroundColor = Color.White,
shape = RoundedCornerShape(4.dp),
modifier = Modifier.padding(8.dp)
) {
Column(modifier = Modifier.fillMaxWidth()) {
Text(
text = counterModel.items[index].name
)
Text(text = "Row A")
}
}
}
@Composable
fun RowB(counterModel: CounterModel, index: Int) {
Card(
backgroundColor = Color.Gray,
shape = RoundedCornerShape(4.dp),
modifier = Modifier.padding(8.dp)
) {
Column(modifier = Modifier.fillMaxWidth()) {
Text(
text = counterModel.items[index].name
)
Text(text = "Row B")
}
}
}