Closed Jve386 closed 4 months ago
La clase QuoteModel es un modelo de datos que facilita la conversión entre JSON y objetos Kotlin, permitiendo manipular fácilmente los datos que se obtienen de una API o de cualquier fuente que proporcione datos en formato JSON. La anotación @SerializedName asegura que los nombres de los campos en el JSON se correspondan correctamente con los nombres de las propiedades en la clase.
data class QuoteModel(
@SerializedName("quote") val quote: String,
@SerializedName("author") val author: String
)
QuoteProvider actúa como un contenedor global para una lista de QuoteModel. El uso del companion object permite acceder a la lista de citas desde cualquier parte de la aplicación sin necesidad de instanciar la clase QuoteProvider. Esto es útil para gestionar datos compartidos o configuraciones que deben ser accesibles globalmente en la aplicación.
class QuoteProvider {
companion object {
var quotes:List<QuoteModel> = emptyList()
}
}
define un cliente de API para realizar una petición GET al endpoint /.json para obtener una lista de citas (QuoteModel). Utiliza anotaciones de Retrofit para especificar el tipo de petición y el endpoint, y retorna un objeto Response que contiene la respuesta de la API. Al ser una función suspendida, puede ser llamada de manera asíncrona usando coroutines en Kotlin, lo que permite manejar operaciones de red sin bloquear el hilo principal de la aplicación.
interface QuoteApiClient {
@GET("/.json")
suspend fun getAllQuotes(): Response<List<QuoteModel>>
}
La clase QuoteService encapsula la lógica necesaria para interactuar con el cliente de API (QuoteApiClient) y obtener una lista de citas. Utiliza Retrofit para realizar la solicitud de red y Kotlin Coroutines para manejar la operación de manera asincrónica y eficiente, cambiando al contexto de I/O para evitar bloquear el hilo principal.
class QuoteService {
private val retrofit = RetrofitHelper.getRetrofit()
suspend fun getQuotes(): List<QuoteModel> {
return withContext(Dispatchers.IO) {
val response = retrofit.create(QuoteApiClient::class.java).getAllQuotes()
response.body() ?: emptyList()
}
}
}
La clase QuoteRepository sirve como una capa de abstracción entre el servicio de red (QuoteService) y el proveedor de datos global (QuoteProvider). Encapsula la lógica para obtener datos desde la API y actualiza el estado global de la aplicación con los datos obtenidos. Este enfoque hace que el código sea más modular y facilita la gestión de datos y su disponibilidad en diferentes partes de la aplicación.
class QuoteRepository {
private val api = QuoteService()
suspend fun getAllQuotes(): List<QuoteModel> {
val response = api.getQuotes()
QuoteProvider.quotes = response
return response
}
}
La clase GetQuotesUseCase encapsula la lógica de negocio para obtener todas las citas de la aplicación. Actúa como un punto de entrada para interactuar con la capa de datos (QuoteRepository) sin exponer directamente los detalles de implementación. Este enfoque sigue los principios de la arquitectura limpia (Clean Architecture) al separar las preocupaciones y facilitar la prueba y la mantenibilidad del código.
class GetQuotesUseCase {
private val repository = QuoteRepository()
suspend operator fun invoke() = repository.getAllQuotes()
}
La clase GetRandomQuoteUseCase encapsula la lógica para obtener una cita aleatoria de la lista de citas disponibles. Actúa como un punto de entrada para interactuar con el proveedor de citas (QuoteProvider) sin exponer directamente los detalles de implementación. Este enfoque sigue los principios de la arquitectura limpia (Clean Architecture) al separar las preocupaciones y facilitar la prueba y la mantenibilidad del código.
class GetRandomQuoteUseCase {
operator fun invoke():QuoteModel?{
val quotes = QuoteProvider.quotes
if(!quotes.isNullOrEmpty()){
val randomNumber = (quotes.indices).random()
return quotes[randomNumber]
}
return null
}
}
La clase QuoteViewModel actúa como un intermediario entre la capa de presentación y la capa de datos de la aplicación, gestionando la lógica de presentación y la interacción con los casos de uso relacionados con las citas. Utiliza LiveData para notificar cambios en los datos de manera reactiva, y coroutines para ejecutar operaciones de manera asíncrona. Este enfoque sigue los principios de la arquitectura de Android Jetpack, facilitando la separación de preocupaciones y la creación de aplicaciones robustas y mantenibles.
class QuoteViewModel : ViewModel() {
val quoteModel = MutableLiveData<QuoteModel>()
val isLoading = MutableLiveData<Boolean>()
private val getQuotesUseCase = GetQuotesUseCase()
private val getRandomQuoteUseCase = GetRandomQuoteUseCase()
fun onCreate() {
viewModelScope.launch {
isLoading.postValue(true)
val result = getQuotesUseCase()
if (!result.isNullOrEmpty()) {
quoteModel.postValue(result[0])
isLoading.postValue(false)
}
}
}
fun randomQuote() {
isLoading.postValue(true)
val quote = getRandomQuoteUseCase()
quote?.let {
quoteModel.postValue(it)
}
isLoading.postValue(false)
}
}
Implementación en el mainActivity y Layout para plasmar la función en el menú principal, utilizando el patrón de arquitectura MVVM (Modelo-Vista-ViewModel) con LiveData para observar cambios en los datos y ejecutar acciones en respuesta a esos cambios.
tvQuote = findViewById(R.id.tvQuote);
quoteViewModel = new ViewModelProvider(this).get(QuoteViewModel.class);
quoteViewModel.onCreate();
quoteViewModel.getQuoteModel().observe(this, new Observer<QuoteModel>() {
@Override
public void onChanged(QuoteModel quoteModel) {
tvQuote.setText(quoteModel.getQuote());
Log.d("MainActivity", "Quote updated: " + quoteModel.getQuote());
}
});
tvQuote.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("MainActivity", "TextView clicked");
quoteViewModel.randomQuote();
}
});
Objeto RetrofitHelper se usa para configurar y proporcionar una instancia de Retrofit preconfigurada. Retrofit es una librería de Java y Android que permite realizar peticiones HTTP de manera sencilla, especialmente útil para consumir APIs REST. En este caso, con un convertidor Gson y una URL base definida.