¿Cómo crear un Loader en el Home Fragment usando XML?
Crear un Loader en una aplicación Android es una tarea esencial para mejorar la experiencia del usuario al mostrar una indicación visual de carga. En esta guía, veremos paso a paso cómo configurar un "Loader" en el Home Fragment de una aplicación Android utilizando XML.
¿Qué es un Loader y cómo se configura?
Un Loader es un componente de interfaz de usuario que indica al usuario que los datos están cargándose. Para crear uno, sigue estos pasos:
Dirígete al archivo XML del Fragment: Ve al archivo XML del fragmento en el que deseas agregar el Loader. Este archivo suele encontrarse en la carpeta res/layout de tu proyecto.
Crear un nuevo Widget: En tu fragmento XML, añade un ProgressBar. Este será el Loader que se mostrará en la aplicación.
Implementación de retraso con Handler: Para simular un tiempo de carga y mejorar la UX, puedes usar un Handler para retrasar la aparición o desaparición del Loader. Por ejemplo, para simular un retraso de 3 segundos:
val handler =Handler(Looper.getMainLooper())handler.postDelayed({hideLoader()},3000)
¿Qué arquitectura se está aplicando y cómo impacta?
En este contexto, se utiliza la arquitectura MVP (Modelo-Vista-Presentador). Esta arquitectura separa la aplicación en tres capas:
Vista: Maneja la interfaz de usuario.
Presentador: Contiene la lógica de negocio y dicta cuándo mostrar el Loader.
Modelo: Gestiona los datos de la aplicación, usualmente interactuando con bases de datos o APIs.
Usar MVP ayuda a mantener un código limpio y escalable. Si necesitas cambiar la manera en que los datos son manejados, puedes realizar modificaciones en la capa específica sin afectar las demás. Este es un gran ejemplo de la claridad y la eficiencia que aporta una arquitectura bien definida en el desarrollo de software.
Perspectivas futuras y arquitecturas alternativas
En clases futuras, se explorará la arquitectura MVVM (Modelo-Vista-Modelo de Vista) que ofrece otras ventajas para el manejo de la interfaz de usuario y la lógica de negocio. Mantente entusiasta, sigue explorando y perfeccionando tus conocimientos en arquitectura de software. Aquí es donde cada detalle cuenta y tu comprensión se profundiza al aplicar estos conceptos en proyectos reales. ¡Adelante y sigue aprendiendo!
HAY VARIAS COSAS QUE NO FUNCIONAN CORRECTAMENTE.
Se supone que al llamar a la lista que tenemos en caché (dentro del HomeInteractor), tendrían que cambiar los nombres, las cantidades de dinero, aparecer fechas y fotos... Y no lo hace. Además debería aparecer una animación junto con la foto de perfil del usuario, que ni sale la foto ni sale la animación en cuanto lanzas la app... Hay muchos errores que no concuerdan con el código que tenemos en archivos y enlaces.
Lo que yo eniendo es que NO se han molestado ni en comprobar si el XML que muestra la fila de transferencias está correcto (que sí lo está) lo que me lleva a entender QUE NO HAN TENIDO GANAS DE HACER EL PASO INTERMEDIO PARA QUE LA VISTA GENERE CADA NUEVO ITEM DEL CACHÉ... Si este curso lo está viendo alguien que no sabe nada de Android, cierra el vídeo y Platzi y se va a otros cursos en otros lugares... Ocurre mucho en todos los cursos. Se saltan pasos SUPERIMPORTANTES para aquellos que están comenzando (y que son los que quieren aprender) y se explican cosas innecesarias que luego no importan.
#Importante
amiguito, el curso en sí no está pensado para crear una app desde cero, no te confundas... el curso se llama Patrones de Diseño... y es para que aprendamos los conceptos, para que aprendamos los diferentes patrones.
Esta puede ser otra forma de crear un delay
Me puedes decir como creaste esa imagen por favor?
Podemos usar los mismos constraints definidos en el recyclerview en nuestro Progress bar para que aparezca en la zona del recycleview, solo para darle un detallito mas en el diseño:
Notar que el proyecto como tal carece de algunos detalles para que pueda ejecutarse correctamente.
Algunos de ellos son:
.
FavoriteTransferAdapter
.
En este se requiere inicializar la lista de favoriteTransferItems en null. Lo hice de la siguiente manera:
classFavoriteTransferAdapter:RecyclerView.Adapter<FavoriteTransferViewHolder>(){privatevarfavoriteTransferItems:List<FavoriteTransfer>?=null override fun onCreateViewHolder(parent:ViewGroup,viewType:Int):FavoriteTransferViewHolder=FavoriteTransferViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.favorite_transfer_row, parent,false)) override fun getItemCount():Int{return favoriteTransferItems?.size ?:0} override fun onBindViewHolder(holder:FavoriteTransferViewHolder,position:Int){// holder.bind(favoriteTransferItems?.get(position)!!) favoriteTransferItems?.get(position)?.let { holder.bind(it)}} fun setData(favoriteTransferItems:List<FavoriteTransfer>){this.favoriteTransferItems= favoriteTransferItems
notifyDataSetChanged()}}
.
.
FavoriteTransferViewHolder
.
En esta clase, no enlazaron las vistas con los datos que traemos de HomeInteractor … razón por la cual se muestran cards con la misma información; información que fué previamente asignada en el xml fragment_home.
Adicional a esto, agregué una función para dar formato a los valores double de amount de forma que se agrega una coma “,” para separar los miles. Acá el código
.
classFavoriteTransferViewHolder(private val view:View):RecyclerView.ViewHolder(view){ @SuppressLint("SetTextI18n") fun bind(item:FavoriteTransfer){ val photoImageView = view.findViewById<ImageView>(R.id.profilePhotoImageView) val name = view.findViewById<TextView>(R.id.nameTextView) val transferAmount = view.findViewById<TextView>(R.id.transferredAmountTextView) val transferTime = view.findViewById<TextView>(R.id.transferTimeTextView)Picasso.get().load(item.photoUrl).into(photoImageView) name.text= item.name transferAmount.text="$${formatingAmountOnDisplay(item)}" transferTime.text= item.date}private fun formatingAmountOnDisplay(item:FavoriteTransfer):String{ val amount = item.amount.toString()varfirstSegment:String=""varsecondSegment:String=""varformatedText:String=""if((amount.length-2)>3&&(amount.length-2)>=6){for(i in0..2){ firstSegment += amount[i].toString()}for(j in3 until amount.length){ secondSegment += amount[j].toString()} formatedText ="${firstSegment},${secondSegment}"}elseif((amount.length-2)>3&&(amount.length-2)>=5){for(i in0..1){ firstSegment += amount[i].toString()}for(j in2 until amount.length){ secondSegment += amount[j].toString()} formatedText ="${firstSegment},${secondSegment}"}elseif((amount.length-2)>3&&(amount.length-2)>=4){for(i in0..0){ firstSegment += amount[i].toString()}for(j in1 until amount.length){ secondSegment += amount[j].toString()} formatedText ="${firstSegment},${secondSegment}"}else{ formatedText = item.amount.toString()}return formatedText
}}
Si se atrasaron en el código pueden descargar el archivo desde la sección 'Archivos y Enlaces', al final de todos esos documentos bajando para abajo le dan a 'descargar todo' y se les bajara un archivo zip, lo extraen y lo abren de forma tradicional en Android Studio.....
(Abren Android Studios y abajo de la opción 'Start a new proyect' abajo hacen click a la opción 'Open an exist proyect' y escogen el archivo descomprimido del zip)
++Para los nuevos en este curso++, al menos 2023
Para el error de
kotlin.UninitializedPropertyAccessException: lateinit property favoriteTransferItems has not been initialized
Deben de modificar el archivo: FavoriteTransferAdapter.kt
// Linea 11 del archivo // Solo quitar lateinit e inicializar con emptyList() como este ejemploprivatevarfavoriteTransferItems:List<FavoriteTransfer>=emptyList()
Ahora bien!!!
Ciertamente hay algunas partes del sistema que no funcionan muy bien, si has seguido la ruta de desarrollo android podrás solucionar cada error, como la foto de perfil que no carga o bien como me ha pasado, hay muchos cambios y algunas depreciaciones en el código pero EL CURSO ES DE ARQUITECTURA así que no debes de ponerle mucha importancia (a menos que quieras meterle mano al código).
Sin embargo la idea es que puedas entender que estamos haciendo.
Les deseo éxitos y que los comentarios negativos de este y los demás videos no los desanime, al final estamos aprendiendo y esto les servirá de experiencia en un ambiente laboral "REAL".
FavoriteTransferAdapter.kt
private var favoriteTransferItems: List<FavoriteTransfer> = arrayListOf()
Esto que dices da error!!!!!!!!!! Cómo se soluciona...!!!!!
Excelente explicación, le estaba batallando para entenderle a esta arquitectura :D, gracias Cristian
Hasta ahora muy bueno el curso y el profe de muy buena calidad.
El profe bien, el curso malo porque no explican nada de la app y luego no se ve el resultado.
Tengo algunas preguntas, en HomeInteractor no me recibe la funcion, y como puedo verlo en mi celular?
Me podrías dar más detalles por aquí por favor y con gusto te ayudo
Para los que tienen el problema de inicialization siempre les va pasar por usar un late init y no inicializarlo y llamarlo, les recomiendo una buena practica es hacer esto
override fun getItemCount():Int=if(this::favoriteTransferItems.isInitialized) favoriteTransferItems.sizeelse0
En la clase "FavoriteTransferViewHolder" debemos agregar alguna lineas de codigo para que las se muestren los datos correctamente, de lo contrario saldra los mismos datos para todas las transferencias usar :
fun bind(item:FavoriteTransfer){ val photoImageView = view.findViewById<ImageView>(R.id.profilePhotoImageView)Picasso.get().load(item.photoUrl).into(photoImageView) val name = view.findViewById<TextView>(R.id.nameTextView) name.text=item.name val transferAmount = view.findViewById<TextView>(R.id.transferredAmountTextView) transferAmount.text=item.amount.toString() val transferTime = view.findViewById<TextView>(R.id.transferTimeTextView) transferTime.text=item.date}
Ademas de esto, la primera imagen no se muestra ya que no se puede tener acceso a URL de la imagen, en mi caso solo busque otra foto de Freddy Vega en internet y copie la url en la clase Home Interactor, y todo funciono correctamente :
Yo , los patrones de disenio lo estoy comprendiendo pero al ver tantos comando nuevos me pierdo ojala que me expliquen mejor la app en su forma basica y lueo sabre modificarla con MVP
Las clases e interfaces que acabamos de crear me salen de color rojo en las pestañas del IDE... No hay ningún error (sale el check verde arriba a la derecha). Alguna idea de por qué sale así??? Cuando corro la app, se carga en el emulador, pero al hacer el launch se me crashea y se cierra... Será también por lo mismo que las pestañas del IDE en rojo???
Alguien puede ayudarme con ello???
Cuando lanzo la app en mi móvil de prueba físico, al girarlo y ponerlo lateral no se ve la pantalla correctamente. Si se supone que hay constraints layouts para que se vea tanto vertical como horizontal en cualquier dispositvo, por qué no se ve bien y no hace scroll????? Alguna idea????