Pat*_*idt 5 android android-jetpack-compose
我目前正在尝试为我的论文编写一个应用程序,目前我正在研究不同的方法。因为我真的很喜欢 Flutter 并且论文要求我使用 Java/Kotlin,所以我想使用 Jetpack compose。
目前,我在尝试更新 ListElements 时陷入困境。
我想要一个显示实验及其状态/结果的列表。一旦我按下按钮,我希望实验运行,并在实验完成后更新其状态。目前,run 方法除了将状态设置为成功之外不执行任何操作。问题是,一旦实验更新其状态,我不知道如何从 ExperimentRow 的 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
)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
}
实验视图模型:
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}")
}
}
Run Code Online (Sandbox Code Playgroud)
实验画面:
@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,
)
}
Run Code Online (Sandbox Code Playgroud)
实验:
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),
}
Run Code Online (Sandbox Code Playgroud)
有几种方法可以解决这个问题,但关键是您需要添加元素的副本(状态已更改)以experiments
触发重组。
一个可能的例子是
data class Experiment(val name: String, val state: ExperimentState, val onStateChanged: (Experiment) -> Unit) {
fun run() {
onStateChanged(this.copy(state = ExperimentState.SUCCESS))
}
}
Run Code Online (Sandbox Code Playgroud)
进而
fun experimentStateChanged(experiment: Experiment) {
val index = experiments.toMutableList().indexOfFirst { it.name == experiment.name }
experiments = experiments.toMutableList().also {
it[index] = experiment
}
}
Run Code Online (Sandbox Code Playgroud)
尽管我怀疑可能有更干净的方法来做到这一点。
归档时间: |
|
查看次数: |
6750 次 |
最近记录: |