Get all pokemon from API

This commit is contained in:
Joren 2024-04-29 15:49:08 +02:00
parent 57cc5c827b
commit e8881a2921
Signed by untrusted user who does not match committer: Joren
GPG Key ID: 280E33DFBC0F1B55
2 changed files with 51 additions and 28 deletions

View File

@ -1,60 +1,68 @@
package com.ti.mobpo.ui
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.gson.annotations.SerializedName
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import retrofit2.Call
import kotlinx.coroutines.launch
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import java.io.IOException
// Data class to hold Pokemon species information
private const val BASE_URL = "https://pokeapi.co/api/v2/";
data class PokemonSpecies(
@SerializedName("name") val name: String,
@SerializedName("url") val url: String
)
// Data class to hold the response from the Pokemon species API
data class PokemonSpeciesResponse(
@SerializedName("results") val results: List<PokemonSpecies>
)
interface PokeApiService {
@GET("pokemon-species/?offset=0&limit=1025")
fun getPokemonSpecies(): Call<PokemonSpeciesResponse>
suspend fun getPokemonSpecies(): PokemonSpeciesResponse
}
class PokeSearchViewModel : ViewModel() {
private val retrofit = Retrofit.Builder()
.baseUrl("https://pokeapi.co/api/v2/")
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build()
private val service = retrofit.create(PokeApiService::class.java)
private val _uiState = MutableStateFlow(PokeSearchUiState())
val uiState: StateFlow<PokeSearchUiState> = _uiState.asStateFlow()
private val _initialPokemonList = MutableStateFlow<List<PokemonSpecies>?>(null)
private val _filteredPokemonList = MutableStateFlow<List<PokemonSpecies>?>(null)
private var pokemonList: List<PokemonSpecies>? = null
val pokemonList: StateFlow<List<PokemonSpecies>?> = _filteredPokemonList.asStateFlow()
init {
fetchPokemonSpecies()
}
private fun fetchPokemonSpecies() {
service.getPokemonSpecies().enqueue(object : retrofit2.Callback<PokemonSpeciesResponse> {
override fun onResponse(call: Call<PokemonSpeciesResponse>, response: retrofit2.Response<PokemonSpeciesResponse>) {
if (response.isSuccessful) {
val speciesResponse = response.body()
pokemonList = speciesResponse?.results
}
}
override fun onFailure(call: Call<PokemonSpeciesResponse>, t: Throwable) {
viewModelScope.launch {
try {
val response = service.getPokemonSpecies()
_initialPokemonList.value = response.results
_filteredPokemonList.value = response.results
} catch (e: IOException) {
/*TODO*/
}
})
}
}
}
fun search(query: String) {
val initialPokemonList = _initialPokemonList.value
if (query.isNotBlank() && initialPokemonList != null) {
val filteredList = initialPokemonList.filter { it.name.contains(query, ignoreCase = true) }
_filteredPokemonList.value = filteredList
} else {
_filteredPokemonList.value = initialPokemonList
}
}
}

View File

@ -1,9 +1,13 @@
package com.ti.mobpo.ui.screens
import com.ti.mobpo.ui.PokeSearchViewModel
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
@ -15,30 +19,41 @@ import androidx.compose.ui.unit.dp
import com.ti.mobpo.R
import com.ti.mobpo.ui.SearchBar
import androidx.lifecycle.viewmodel.compose.viewModel
import com.ti.mobpo.ui.PokeSearchViewModel
@Composable
fun PokeSearchScreen(pokesearchViewModel: PokeSearchViewModel = viewModel()){
val pokesearchUiState by pokesearchViewModel.uiState.collectAsState()
PokeSearch()
fun PokeSearchScreen(pokeSearchViewModel: PokeSearchViewModel = viewModel()) {
PokeSearch(pokeSearchViewModel)
}
@Composable
fun PokeSearch() {
Column (
fun PokeSearch(pokeSearchViewModel: PokeSearchViewModel = viewModel()) {
val searchResults by pokeSearchViewModel.pokemonList.collectAsState()
Column(
verticalArrangement = Arrangement.Top,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxSize()
.padding(20.dp)
) {
SearchBar(stringResource(R.string.input_field_label)){ value ->
run {
println(value)
SearchBar(stringResource(R.string.input_field_label)) { value ->
pokeSearchViewModel.search(value)
}
Spacer(modifier = Modifier.height(16.dp))
searchResults?.let { results ->
if (results.isNotEmpty()) {
results.forEach { pokemon ->
Text(text = pokemon.name)
}
} else {
Text("No results found")
}
}
}
}
@Preview(showBackground = true)
@Composable
fun PokeSearchApp(){