当 ViewModel 使用 Java 且 UI 使用 Jetpack Compose (Kotlin) 时,如何观察列表中的变化

问题描述 投票:0回答:1

我正在将应用程序从 View 迁移到 Compose。该应用程序是用 Java 编写的,因此我需要将 UI 迁移到 Kotlin。 我更喜欢尽可能逐步地进行,因此我将 ViewModel 保留在 Java 中。

UI 是卡片的惰性列。长按卡片可切换其“已选择”状态。它将一个事件发送到 ViewModel - 在包含所选卡片 ID 的列表中添加/删除其 ID。 我希望 UI 能够观察 ID 列表中的变化。 目前,我使用一种解决方法:一个可观察的布尔值,它会随着 ID 列表中的每次更改而切换。我想知道是否有更好的方法。

一些代码: UI部分-显示卡片的功能:

@OptIn(ExperimentalFoundationApi::class) @Composable private fun DisplayAlarmItem(alarmItem: AlarmItem) { // Force this function to be called when list of selected changes val selectToggle by parent!!.alarmViewModel.selectToggleObserve.observeAsState( ) val toggled = if (selectToggle!=null && selectToggle as Boolean) "A" else "B" // Get list of selected alarms and mark this item as selected(yes/no) val selectedAlarmList by parent!!.alarmViewModel.selectedItems.observeAsState() val filterList = selectedAlarmList?.filter { it.equals(alarmItem.createTime.toInt()) } var selected= (filterList != null && filterList.isNotEmpty()) val backgroundColor = if (selected) MaterialTheme.colorScheme.surfaceVariant else MaterialTheme.colorScheme.surface val currentAlpha = if (alarmItem.isActive) 1.0f else 0.3f Card( modifier = Modifier .padding(5.dp) .fillMaxWidth() .combinedClickable( onLongClick = { AlarmItemLongClicked(alarmItem.getCreateTime()) }, onClickLabel = "Edit Alarm" ) { AlarmItemEdit(alarmItem, true) } .background(MaterialTheme.colorScheme.surface) .wrapContentHeight(), shape = MaterialTheme.shapes.small, elevation = CardDefaults.elevatedCardElevation(5.dp), colors = CardDefaults.cardColors(containerColor = backgroundColor), ) { ConstraintLayout(modifier = Modifier.fillMaxSize()) { val refLabel = createRef() val refBell = createRef() val refAlarmTime = createRef() val refAlarmActive = createRef() val refAmPm24h = createRef() val refWeekdays = createRef() } } }

现在,长按回调:

private fun AlarmItemLongClicked(id: Long) { // get the list of alarms //List<AlarmItem> alarmItems = parent.alarmViewModel.getAlarmList().getValue(); //if (alarmItems==null) return; // Update the list of the selected items - simply toggle parent!!.alarmViewModel.toggleSelection(id) // Modify toolbar according to number of selected items parent!!.UpdateOptionMenu() // Inform the ViewModel that the selection List was changed parent?.alarmViewModel?.selectToggleObserve() }

在 ViewModel 上,从所选 ID 列表中添加/删除 ID 的代码:

public void toggleSelection(long id){ int index = selectedItems.indexOf((int)id); if (index >=0) selectedItems.remove(index); else selectedItems.add((int)id); LiveSelectedItems.setValue(selectedItems); selectToggleObserve();

}

以上属性的定义:

private final MutableLiveData<ArrayList<Integer>> LiveSelectedItems; private final ArrayList<Integer> selectedItems;

	
java kotlin arraylist android-jetpack-compose viewmodel
1个回答
0
投票
State

需要知道其值何时更新,但它无法跟踪

List
中的更改。要触发
State
更新,您需要创建一个新的集合实例,而不是使用相同的
LiveData
实例更新
ArrayList
查看模型:

private final MutableLiveData<ArrayList<Integer>> liveSelectedItems = new MutableLiveData<>(new ArrayList<>()); public final LiveData<ArrayList<Integer>> selectedItems = liveSelectedItems; public void toggleSelection(int id) { var currentList = Objects.requireNonNull(liveSelectedItems.getValue()); var newList = new ArrayList<>(currentList); int index = currentList.indexOf(id); if (index >= 0) { newList.remove(index); } else { newList.add(id); } liveSelectedItems.setValue(newList); }

可组合示例:

val selectedItems by viewModel.selectedItems.observeAsState(ArrayList()) Column { repeat(10) { index -> Card( modifier = Modifier .padding(5.dp) .fillMaxWidth() .clickable { viewModel.toggleSelection(index) }, ) { Text("Item $index selected: ${selectedItems.contains(index)}") } } }

	
© www.soinside.com 2019 - 2024. All rights reserved.