Asynchrones Laden in Jetpack Compose geht nicht?
Hallo, ich habe folgenden Code in meiner Android Jetpack Compose App, wenn ich die App starte bleibt der Bildschirm wo die Elemente der LazyColumn sein sollten jedoch leer. In der Konsole werden aber die Namen von den Filmen angezeigt (siehe println in der getTrendingMoviesAsync() Methode)
Code in der MainScreen Klasse:
val movies by remember { mutableStateOf(ArrayList<JSONObject>(emptyList())) }
val coroutineScope = rememberCoroutineScope()
LaunchedEffect(true) {
coroutineScope.launch {
val result = getTrendingMoviesAsync()
if (result != null){
movies.addAll(result)
}
}
}
LazyColumn(modifier = Modifier.padding(top = 135.dp)){
items(movies){ movie ->
Text(text = movie.getString("title"))
Spacer(modifier = Modifier.height(10.dp))
}
}
Code von der Methode:
suspend fun getTrendingMoviesAsync(): ArrayList<JSONObject>? {
return withContext(Dispatchers.IO) {
try {
val movies = ArrayList<JSONObject>()
val client = OkHttpClient()
val request = Request.Builder()
.url("https://api.themoviedb.org/3/trending/movie/week?language=de-DE")
.get()
.addHeader("accept", "application/json")
.addHeader(
"Authorization",
"Bearer <apikey>"
)
.build()
val response = client.newCall(request).execute()
val json = JSONObject(response.body()?.string())
val results = json.getJSONArray("results")
for (i in 0 until results.length().coerceAtMost(30)) {
val movie = results.getJSONObject(i)
println(movie.getString("title"))
movies.add(movie)
}
movies
} catch (e: Exception) {
e.printStackTrace()
null
}
}
}
Kann mir jemand weiterhelfen?
1 Antwort
Es scheint, dass dein Code für das asynchrone Laden von Filmen mit Jetpack Compose gut aussieht. Der Hauptgrund dafür, dass die LazyColumn nicht korrekt gerendert wird, könnte an der mutableStateOf-Implementierung liegen. Beachte, dass mutableStateOf ein Werttyp ist, und wenn du direkt auf den Wert zugreifst und ihn aktualisierst, wird die Compose-UI möglicherweise nicht korrekt informiert.
Hier sind einige mögliche Verbesserungen, die du vornehmen könntest:
1. **Verwende ein State-Objekt für den Film-Status:**
```kotlin
var moviesState by remember { mutableStateOf(ArrayList<JSONObject>(emptyList())) }
```
2. **Aktualisiere den Status mit dem State-Objekt:**
```kotlin
LaunchedEffect(true) {
coroutineScope.launch {
val result = getTrendingMoviesAsync()
if (result != null){
moviesState = ArrayList(result)
}
}
}
```
3. **Verwende moviesState beim Rendern der LazyColumn:**
```kotlin
LazyColumn(modifier = Modifier.padding(top = 135.dp)){
items(moviesState){ movie ->
Text(text = movie.getString("title"))
Spacer(modifier = Modifier.height(10.dp))
}
}
```
Wenn das Problem weiterhin besteht, könntest du auch versuchen, die LazyColumn durch ein anderes Compose-Widget zu ersetzen, um festzustellen, ob das Rendering-Problem spezifisch für die LazyColumn ist.
Außerdem ist es wichtig sicherzustellen, dass du die neueste Version von Jetpack Compose und Kotlin Coroutines verwendest, da es möglicherweise Aktualisierungen oder Fixes für solche Probleme gibt.