Как заставить перезагрузить пользовательский интерфейс с помощью Jetpack Compose?Android

Форум для тех, кто программирует под Android
Ответить Пред. темаСлед. тема
Anonymous
 Как заставить перезагрузить пользовательский интерфейс с помощью Jetpack Compose?

Сообщение Anonymous »

У меня есть объект GameState, который обновляется при каждом изменении состояния игры, а некоторые элементы пользовательского интерфейса не обновляются должным образом. Я хотел бы просто вызывать функцию перезагрузки всякий раз, когда данные перезагружаются, чтобы мне не приходилось беспокоиться о том, что они не обновляются.

Код: Выделить всё

package dev.madcatter.lostworld

import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.VerticalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.lifecycleScope
import dev.madcatter.lostworld.data.GameState
import dev.madcatter.lostworld.ui.Console
import dev.madcatter.lostworld.ui.Turns
import dev.madcatter.lostworld.ui.theme.LostWorldTheme
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

class MainActivity : ComponentActivity() {

private lateinit var myApp: LostWorldApp
private lateinit var gameState: MutableState
private var updateTicker: MutableState  = mutableStateOf(0)

@OptIn(ExperimentalMaterial3Api::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

myApp = application as? LostWorldApp ?: throw IllegalStateException("Application class is not LostWorldApp")
gameState = mutableStateOf(myApp.gameState!!)

enableEdgeToEdge()
setContent {
LostWorldTheme {
MainContent()
}
}
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun MainContent() {
Scaffold(
topBar = {
TopAppBar(
title = { Text(text = "Lost World") },
actions = {
IconButton(onClick = {
gameState.value.debug("---\n\nReload button clicked.")
reloadGameState()
}) {
Icon(
imageVector = Icons.Default.Refresh,
contentDescription = "Reload"
)
}
IconButton(onClick = {
startActivity(Intent(this@MainActivity, SettingsActivity::class.java))
}) {
Icon(
imageVector = Icons.Default.Settings,
contentDescription = "Settings"
)
}
}
)
},
content = { innerPadding ->
// Main content here
Row(modifier = Modifier.padding(innerPadding)) {
Turns(
gameState.value,
modifier = Modifier
.padding(16.dp)
.weight(0.25f)
.fillMaxHeight()
)

VerticalDivider(
color = MaterialTheme.colorScheme.outline,
modifier = Modifier
.width(1.dp)
.align(Alignment.CenterVertically)
.fillMaxHeight(0.85f)
)

Console(
gameState.value,
modifier = Modifier
.padding(16.dp)
.weight(0.75f)
.fillMaxHeight()
)
}
}
)
}

override fun onStart() {
super.onStart()

// Run the reload after a short delay using lifecycleScope
lifecycleScope.launch(Dispatchers.Main) {
delay(200) // Wait 200 milliseconds, or adjust as necessary
reloadGameState()
}
}

private fun reloadGameState() {
gameState.value.reload()
gameState.value = myApp.gameState!!
updateTicker.value++
}
}
Что я пробовал:
  • Я использовал onStart() для перезагрузки gameState всякий раз, когда действие выходит на передний план, добавляя небольшая задержка, чтобы дать возможность пользовательскому интерфейсу стабилизироваться.
  • Чтобы обновить пользовательский интерфейс, я переназначал gameState, что иногда приводило к очистке вывода.
  • Переназначение gameState приводил к проблемам с очисткой состояния, например к потере вывода на консоль.
  • Сейчас я изучаю, как лучше всего обновить только необходимые свойства gameState, чтобы вызвать обновление пользовательского интерфейса без потери существующих данных.
    li>


Подробнее здесь: https://stackoverflow.com/questions/791 ... ck-compose
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Android»