Get all pokemon from API
This commit is contained in:
parent
57cc5c827b
commit
e8881a2921
@ -1,60 +1,68 @@
|
|||||||
package com.ti.mobpo.ui
|
package com.ti.mobpo.ui
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import retrofit2.Call
|
import kotlinx.coroutines.launch
|
||||||
import retrofit2.Retrofit
|
import retrofit2.Retrofit
|
||||||
import retrofit2.converter.gson.GsonConverterFactory
|
import retrofit2.converter.gson.GsonConverterFactory
|
||||||
import retrofit2.http.GET
|
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(
|
data class PokemonSpecies(
|
||||||
@SerializedName("name") val name: String,
|
@SerializedName("name") val name: String,
|
||||||
@SerializedName("url") val url: String
|
@SerializedName("url") val url: String
|
||||||
)
|
)
|
||||||
|
|
||||||
// Data class to hold the response from the Pokemon species API
|
|
||||||
data class PokemonSpeciesResponse(
|
data class PokemonSpeciesResponse(
|
||||||
@SerializedName("results") val results: List<PokemonSpecies>
|
@SerializedName("results") val results: List<PokemonSpecies>
|
||||||
)
|
)
|
||||||
|
|
||||||
interface PokeApiService {
|
interface PokeApiService {
|
||||||
@GET("pokemon-species/?offset=0&limit=1025")
|
@GET("pokemon-species/?offset=0&limit=1025")
|
||||||
fun getPokemonSpecies(): Call<PokemonSpeciesResponse>
|
suspend fun getPokemonSpecies(): PokemonSpeciesResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
class PokeSearchViewModel : ViewModel() {
|
class PokeSearchViewModel : ViewModel() {
|
||||||
private val retrofit = Retrofit.Builder()
|
private val retrofit = Retrofit.Builder()
|
||||||
.baseUrl("https://pokeapi.co/api/v2/")
|
.baseUrl(BASE_URL)
|
||||||
.addConverterFactory(GsonConverterFactory.create())
|
.addConverterFactory(GsonConverterFactory.create())
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
private val service = retrofit.create(PokeApiService::class.java)
|
private val service = retrofit.create(PokeApiService::class.java)
|
||||||
|
|
||||||
private val _uiState = MutableStateFlow(PokeSearchUiState())
|
private val _initialPokemonList = MutableStateFlow<List<PokemonSpecies>?>(null)
|
||||||
val uiState: StateFlow<PokeSearchUiState> = _uiState.asStateFlow()
|
private val _filteredPokemonList = MutableStateFlow<List<PokemonSpecies>?>(null)
|
||||||
|
|
||||||
private var pokemonList: List<PokemonSpecies>? = null
|
val pokemonList: StateFlow<List<PokemonSpecies>?> = _filteredPokemonList.asStateFlow()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
fetchPokemonSpecies()
|
fetchPokemonSpecies()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fetchPokemonSpecies() {
|
private fun fetchPokemonSpecies() {
|
||||||
service.getPokemonSpecies().enqueue(object : retrofit2.Callback<PokemonSpeciesResponse> {
|
viewModelScope.launch {
|
||||||
override fun onResponse(call: Call<PokemonSpeciesResponse>, response: retrofit2.Response<PokemonSpeciesResponse>) {
|
try {
|
||||||
if (response.isSuccessful) {
|
val response = service.getPokemonSpecies()
|
||||||
val speciesResponse = response.body()
|
_initialPokemonList.value = response.results
|
||||||
pokemonList = speciesResponse?.results
|
_filteredPokemonList.value = response.results
|
||||||
}
|
} catch (e: IOException) {
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(call: Call<PokemonSpeciesResponse>, t: Throwable) {
|
|
||||||
/*TODO*/
|
/*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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,13 @@
|
|||||||
package com.ti.mobpo.ui.screens
|
package com.ti.mobpo.ui.screens
|
||||||
|
|
||||||
|
import com.ti.mobpo.ui.PokeSearchViewModel
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
@ -15,30 +19,41 @@ import androidx.compose.ui.unit.dp
|
|||||||
import com.ti.mobpo.R
|
import com.ti.mobpo.R
|
||||||
import com.ti.mobpo.ui.SearchBar
|
import com.ti.mobpo.ui.SearchBar
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.ti.mobpo.ui.PokeSearchViewModel
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PokeSearchScreen(pokesearchViewModel: PokeSearchViewModel = viewModel()){
|
fun PokeSearchScreen(pokeSearchViewModel: PokeSearchViewModel = viewModel()) {
|
||||||
val pokesearchUiState by pokesearchViewModel.uiState.collectAsState()
|
PokeSearch(pokeSearchViewModel)
|
||||||
PokeSearch()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PokeSearch() {
|
fun PokeSearch(pokeSearchViewModel: PokeSearchViewModel = viewModel()) {
|
||||||
Column (
|
val searchResults by pokeSearchViewModel.pokemonList.collectAsState()
|
||||||
|
|
||||||
|
Column(
|
||||||
verticalArrangement = Arrangement.Top,
|
verticalArrangement = Arrangement.Top,
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(20.dp)
|
.padding(20.dp)
|
||||||
) {
|
) {
|
||||||
SearchBar(stringResource(R.string.input_field_label)){ value ->
|
SearchBar(stringResource(R.string.input_field_label)) { value ->
|
||||||
run {
|
pokeSearchViewModel.search(value)
|
||||||
println(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)
|
@Preview(showBackground = true)
|
||||||
@Composable
|
@Composable
|
||||||
fun PokeSearchApp(){
|
fun PokeSearchApp(){
|
||||||
|
Loading…
x
Reference in New Issue
Block a user