WhatsApp

  

Skeletons en Android

Aprende a hacer Skeletons en Android con ejemplos
Cómo hacer Skeletons en Android Studio

En este tutorial aprenderás a implementar un efecto de carga visual (Shimmer Effect) en una aplicación Android que utiliza un RecyclerView para mostrar una lista de usuarios. Este efecto simula una animación mientras los datos reales se están obteniendo.

1. Crear un nuevo proyecto

Inicia un proyecto en Android Studio seleccionando Empty Activity


Configura el nombre y deja las opciones por defecto (Kotlin, API 24 o superior).

Veremos la interfaz usual de android studio: 

2. Agregar dependencias en build.gradle

Dirigete a el archivo build.gradle del modulo android. Agrega las siguientes lineas al final del codigo, que es la libreria de shimmer de Facebook.


implementation 'com.facebook.shimmer:shimmer:0.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.recyclerview:recyclerview:1.3.1'
   

3. Diseñar el layout principal (activity_main.xml)

En este archivo le daras diseño a tu aplicación, tener en cuenta el siguiente código:


<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout   xmlns:android="http://schemas.android.com/apk/res/android"   xmlns:app="http://schemas.android.com/apk/res-auto"   xmlns:tools="http://schemas.android.com/tools"   android:layout_width="match_parent"   android:layout_height="match_parent"   tools:context=".MainActivity">   <LinearLayout       android:id="@+id/llContenedor"       android:layout_width="match_parent"       android:layout_height="match_parent"       android:visibility="gone"       android:orientation="vertical"       app:layout_constraintBottom_toBottomOf="parent"       app:layout_constraintEnd_toEndOf="parent"       app:layout_constraintStart_toStartOf="parent"       app:layout_constraintTop_toTopOf="parent">​       <androidx.recyclerview.widget.RecyclerView           android:id="@+id/rvUsuarios"           android:layout_width="match_parent"           android:layout_height="match_parent" />   </LinearLayout>   <com.facebook.shimmer.ShimmerFrameLayout       android:layout_width="match_parent"       android:layout_height="match_parent"       app:shimmmer_auto_start="true"       app:layout_constraintEnd_toEndOf="parent"       app:layout_constraintStart_toStartOf="parent"       app:layout_constraintTop_toTopOf="parent">             <LinearLayout           android:id="@+id/llCargandor"           android:layout_width="match_parent"           android:layout_height="match_parent"           android:orientation="vertical"           app:layout_cosntraintBottom_toBottomOf="parent"           app:layout_constraintEnd_toEndOf="parent"           app:layout_constraintStart_toStartOf="parent"           app:layout_constraintTop_toTopOf="parent">                    <include layout="@layout/cargando" />           <include layout="@layout/cargando" />           <include layout="@layout/cargando" />           <include layout="@layout/cargando" />                 </LinearLayout   </com.facebook.shimmer.ShimmerFrameLayout></androidx.constraintlayout.widget.ConstraintLayout>
    

4. Crear recursos para el skeleton

Observa que no existe el layout cargando, vamos a crearlo en res/layout
Antes de eso, crear dos archivos permitan dibujar un circulo y aplicar un background. 
En la carpeta drawable, tomar como ejemplo los codigos: 

<!-- Para shape_circle.xml--><?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="oval">    <solid android:color="#E0E0E0" /></shape><!-- Para skeleton_background.xml--->skeleton_background.xml<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle">    <solid android:color="#E0E0E0" />    <corners android:radius="8dp" /></shape>

5. Crear  el layout "Cargando"

Ya que tenemos las configuraciones antes mencionadas, crear cargando.xml, tomando como ejemplo el siguiente codigo: 


<androidx.constraintlayout.widget.ConstraintLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="150dp"
   android:layout_marginHorizontal="20dp"
   android:layout_marginVertical="10dp"
   android:background="@drawable/skeleton_background"
   android:elevation="6dp"
   android:layout_margin="8dp">
   <FrameLayout
      ;
   <FrameLayout
       android:id="@+id/tvPuesto1"
       android:layout_width="100dp"
       android:layout_height="15dp"
       android:background="#c8c8c8"
       app:layout_constraintTop_toTopOf="@+id/ivCredencial"
       app:layout_constraintBottom_toBottomOf="@+id/tvPuesto0"
       app:layout_constraintStart_toEndOf="@+id/ivCredencial"
       app:layout_constraintEnd_toStartOf="@+id/tvPuesto2" />
   <FrameLayout
       android:id="@+id/tvPuesto0"
       android:layout_width="50dp"
       android:layout_height="5dp"
       android:background="#c8c8c8"
       app:layout_constraintTop_toTopOf="@+id/ivCredencial"
       app:layout_constraintBottom_toBottomOf="@+id/ivCredencial"
       app:layout_constraintStart_toEndOf="@+id/ivCredencial"
       app:layout_constraintEnd_toStartOf="@+id/tvPuesto2" />
   <FrameLayout
       android:id="@+id/tvPuesto4"
       android:layout_width="100dp"
       android:layout_height="5dp"
       android:background="#c8c8c8"
       android:layout_marginTop="8dp"
       app:layout_constraintTop_toBottomOf="@+id/tvPuesto0"
       app:layout_constraintStart_toStartOf="@+id/tvPuesto1"
       app:layout_constraintEnd_toEndOf="@+id/tvPuesto1" />
   <FrameLayout
       android:id="@+id/tvPuesto6"
       android:layout_width="50dp"
       android:layout_height="5dp"
       android:background="#c8c8c8"
       android:layout_marginTop="8dp"
       app:layout_constraintTop_toBottomOf="@+id/tvPuesto4"
       app:layout_constraintStart_toStartOf="@+id/tvPuesto4"
       app:layout_constraintEnd_toEndOf="@+id/tvPuesto4" />
   <FrameLayout
       android:id="@+id/tvPuesto2"
       android:layout_width="100dp"
       android:layout_height="15dp"
       android:background="#c8c8c8"
       app:layout_constraintTop_toTopOf="@+id/tvPuesto1"
       app:layout_constraintBottom_toBottomOf="@+id/tvPuesto1"
       app:layout_constraintStart_toEndOf="@+id/tvPuesto1"
       app:layout_constraintEnd_toEndOf="parent" />
   <FrameLayout
       android:id="@+id/tvPuesto03"
       android:layout_width="50dp"
       android:layout_height="5dp"
       android:background="#c8c8c8"
       app:layout_constraintTop_toTopOf="@+id/tvPuesto0"
       app:layout_constraintBottom_toBottomOf="@+id/tvPuesto0"
       app:layout_constraintStart_toEndOf="@+id/tvPuesto2"
       app:layout_constraintEnd_toStartOf="@id/tvPuesto2" />
   <FrameLayout
       android:id="@+id/tvPuesto5"
       android:layout_width="100dp"
       android:layout_height="5dp"
       android:background="#c8c8c8"
       android:layout_marginTop="8dp"
       app:layout_constraintTop_toBottomOf="@+id/tvPuesto03"
       app:layout_constraintStart_toStartOf="@+id/tvPuesto2"
       app:layout_constraintEnd_toEndOf="@+id/tvPuesto2" />
</androidx.constraintlayout.widget.ConstraintLayout>



6. Controlar el shimmer en Kotlin

Hasta este punto tenemos todo lo necesario, para controlar nuestros shimmers. Eso lo tenemos que hacer en un archivo kotlin.


package com.example.skeletons_xdimport android.os.Bundleimport android.os.Handlerimport android.os.Looperimport android.view.Viewimport android.widget.LinearLayoutimport androidx.appcompat.app.AppCompatActivityimport androidx.recyclerview.widget.RecyclerViewimport com.facebook.shimmer.ShimmerFrameLayoutclass MainActivity : AppCompatActivity() {
    private lateinit var shimmerLayout: ShimmerFrameLayout
    private lateinit var llContenedor: LinearLayout
    private lateinit var rvUsuarios: RecyclerView
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        shimmerLayout = findViewById(R.id.shimmer)
        llContenedor = findViewById(R.id.llContenedor)
        rvUsuarios = findViewById(R.id.rvUsuarios)
        shimmerLayout.startShimmer()
        Handler(Looper.getMainLooper()).postDelayed({
            shimmerLayout.stopShimmer()
            shimmerLayout.visibility = View.GONE
            llContenedor.visibility = View.VISIBLE
        }, 3000)
    }
}
    

7. Ajustar el tema en themes.xml

Desues de ajustar el tema, puedes probar el codigo. 


<style name="Theme.Skeletons_xd" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/purple_500</item>
    <item name="colorPrimaryDark">@color/purple_700</item>
    <item name="colorAccent">@color/teal_200</item>
</style>
    


Jesús Alejandro Tenorio 12 noviembre, 2025
Compartir
Iniciar sesión dejar un comentario

  
Algoritmo del Factorial en Python: Guía Completa, Ejemplos y Buenas Prácticas
Aprende todo sobre el algoritmo factorial, su implementación en Python (recursiva, iterativa, memoizada y con functools), análisis de complejidad, optimizaciones y casos de uso reales.