我目前正试图为我的论文写一个应用程序,目前,我正在寻找不同的方法。因为我非常喜欢flutter,而且论文要求我使用java/kotlin,所以我想使用jetpack编写。
目前,我一直在尝试更新列表元素。
我想要一份显示实验及其状态/结果的列表。一旦我按下按钮,我希望实验运行,并在他们完成后更新他们的状态。目前,run方法除了将state设置为success之外什么也不做。问题是我不知道一旦一个实验更新了它的状态,如何从实验行的viewmodel触发一个重新组合。
实验活动:
class ExperimentsActivity : AppCompatActivity() {
val exViewModel by viewModels<ExperimentViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//For now this is just Dummy Data and will be replaced
exViewModel.experiments += listOf(
Experiment("Test1", exViewModel::experimentStateChanged),
Experiment("Strongbox", exViewModel::experimentStateChanged)
)
setContent {
TpmTheme {
// A surface container using the 'background' color from the theme
Surface {
ExperimentScreen(
exViewModel.experiments,
exViewModel::startTests
)
}
}
}
}
}
实验视图模型:
class ExperimentViewModel : ViewModel() {
var experiments by mutableStateOf(listOf<Experiment>())
fun startTests() {
for (exp in experiments) {
exp.run()
}
}
fun experimentStateChanged(experiment: Experiment) {
Log.i("ViewModel", "Changed expState of ${experiment.name} to ${experiment.state}")
// HOW DO I TRIGGER A RECOMPOSE OF THE EXPERIMENTROW FOR THE experiment????
//experiments = experiments.toMutableList().also { it.plus(experiment) }
Log.i("Vi", "Size of Expirments: ${experiments.size}")
}
}
实验屏幕:
@Composable
fun ExperimentScreen(
experiments: List<Experiment>,
onStartExperiments: () -> Unit
) {
Column {
LazyColumnFor(
items = experiments,
modifier = Modifier.weight(1f),
contentPadding = PaddingValues(top = 8.dp),
) { ep ->
ExperimentRow(
experiment = ep,
modifier = Modifier.fillParentMaxWidth(),
)
}
Button(
onClick = { onStartExperiments() },
modifier = Modifier.padding(16.dp).fillMaxWidth(),
) {
Text("Run Tests")
}
}
}
@Composable
fun ExperimentRow(experiment: Experiment, modifier: Modifier = Modifier) {
Row(
modifier = modifier
.padding(horizontal = 16.dp, vertical = 8.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(experiment.name)
Icon(
asset = experiment.state.vAsset,
)
}
实验:
class Experiment(val name: String, val onStateChanged: (Experiment) -> Unit) {
var state: ExperimentState = ExperimentState.DEFAULT
set(value) {
field = value
onStateChanged(this)
}
fun run() {
state = ExperimentState.SUCCESS;
}
}
enum class ExperimentState(val vAsset: VectorAsset) {
DEFAULT(Icons.Default.Info),
RUNNING(Icons.Default.Refresh),
SUCCESS(Icons.Default.Done),
FAILED(Icons.Default.Warning),
}
1条答案
按热度按时间lsmepo6l1#
有几种方法可以解决这个问题,但关键是您需要将元素的副本(状态已更改)添加到
experiments
触发重新编译。一个可能的例子是
然后
尽管我怀疑有更干净的方法。