From 308e79a52c5f305de6b46cf7d3b0fbb58d6f4b5a Mon Sep 17 00:00:00 2001 From: 230417 <230417@epvc.pt> Date: Thu, 16 Apr 2026 10:27:11 +0100 Subject: [PATCH] =?UTF-8?q?altera=C3=A7=C3=B5es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/example/api/MainActivity.kt | 79 +++++++++++-------- .../api/network/RickAndMortyService.kt | 6 +- .../api/viewmodel/CharacterViewModel.kt | 15 +++- 3 files changed, 61 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/com/example/api/MainActivity.kt b/app/src/main/java/com/example/api/MainActivity.kt index 9554438..0b9918e 100644 --- a/app/src/main/java/com/example/api/MainActivity.kt +++ b/app/src/main/java/com/example/api/MainActivity.kt @@ -4,23 +4,11 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge -import androidx.compose.foundation.layout.Box -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.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material3.Button -import androidx.compose.material3.CircularProgressIndicator -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBar -import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue +import androidx.compose.material3.* +import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @@ -47,37 +35,58 @@ fun CharacterScreen(viewModel: CharacterViewModel = viewModel()) { val characters by viewModel.characters.collectAsState() val isLoading by viewModel.isLoading.collectAsState() val error by viewModel.error.collectAsState() + val searchQuery by viewModel.searchQuery.collectAsState() Scaffold( topBar = { - TopAppBar(title = { Text("Rick and Morty Characters") }) + TopAppBar(title = { Text("Rick and Morty Finder") }) } ) { innerPadding -> - Box( + Column( modifier = Modifier .fillMaxSize() .padding(innerPadding) ) { - when { - isLoading -> { - CircularProgressIndicator(modifier = Modifier.align(Alignment.Center)) - } - error != null -> { - Column( - modifier = Modifier.align(Alignment.Center), - horizontalAlignment = Alignment.CenterHorizontally - ) { - Text(text = error ?: "Erro desconhecido") - Spacer(modifier = Modifier.height(8.dp)) - Button(onClick = { viewModel.fetchCharacters() }) { - Text("Tentar novamente") + // Barra de Busca - Isso faz o app "fazer alguma coisa" interativa + OutlinedTextField( + value = searchQuery, + onValueChange = { viewModel.onSearchQueryChange(it) }, + modifier = Modifier + .fillMaxWidth() + .padding(8.dp), + placeholder = { Text("Pesquisar personagem (ex: Rick, Morty...)") }, + label = { Text("Buscar por Nome") }, + singleLine = true + ) + + Box(modifier = Modifier.weight(1f)) { + when { + isLoading && characters.isEmpty() -> { + CircularProgressIndicator(modifier = Modifier.align(Alignment.Center)) + } + error != null && characters.isEmpty() -> { + Column( + modifier = Modifier.align(Alignment.Center), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text(text = error ?: "Erro desconhecido") + Spacer(modifier = Modifier.height(16.dp)) + Button(onClick = { viewModel.fetchCharacters(searchQuery) }) { + Text("Tentar novamente") + } } } - } - else -> { - LazyColumn { - items(characters) { character -> - CharacterItem(character = character) + characters.isEmpty() && !isLoading -> { + Text( + text = "Nenhum resultado encontrado.", + modifier = Modifier.align(Alignment.Center) + ) + } + else -> { + LazyColumn { + items(characters) { character -> + CharacterItem(character = character) + } } } } diff --git a/app/src/main/java/com/example/api/network/RickAndMortyService.kt b/app/src/main/java/com/example/api/network/RickAndMortyService.kt index 87b34f1..5c5219e 100644 --- a/app/src/main/java/com/example/api/network/RickAndMortyService.kt +++ b/app/src/main/java/com/example/api/network/RickAndMortyService.kt @@ -2,8 +2,12 @@ package com.example.api.network import com.example.api.model.CharacterResponse import retrofit2.http.GET +import retrofit2.http.Query interface RickAndMortyService { @GET("character") - suspend fun getCharacters(): CharacterResponse + suspend fun getCharacters( + @Query("page") page: Int? = null, + @Query("name") name: String? = null + ): CharacterResponse } diff --git a/app/src/main/java/com/example/api/viewmodel/CharacterViewModel.kt b/app/src/main/java/com/example/api/viewmodel/CharacterViewModel.kt index 019f19d..9c812ee 100644 --- a/app/src/main/java/com/example/api/viewmodel/CharacterViewModel.kt +++ b/app/src/main/java/com/example/api/viewmodel/CharacterViewModel.kt @@ -18,19 +18,28 @@ class CharacterViewModel : ViewModel() { private val _error = MutableStateFlow(null) val error: StateFlow = _error + private val _searchQuery = MutableStateFlow("") + val searchQuery: StateFlow = _searchQuery + init { fetchCharacters() } - fun fetchCharacters() { + fun onSearchQueryChange(query: String) { + _searchQuery.value = query + fetchCharacters(query) + } + + fun fetchCharacters(name: String? = null) { viewModelScope.launch { _isLoading.value = true _error.value = null try { - val response = RetrofitClient.apiService.getCharacters() + val response = RetrofitClient.apiService.getCharacters(name = name) _characters.value = response.results } catch (e: Exception) { - _error.value = "Erro ao carregar personagens: ${e.localizedMessage}" + _characters.value = emptyList() + _error.value = if (name != null) "Nenhum personagem encontrado com esse nome." else "Erro ao carregar personagens." } finally { _isLoading.value = false }