flutter_skeleton_loader 2.0.0
flutter_skeleton_loader: ^2.0.0 copied to clipboard
Crea efectos de carga elegantes y personalizables en Flutter con soporte para widgets comunes mientras se cargan datos.
Flutter Skeleton Loader v2.0 #
Biblioteca Flutter para crear efectos de carga (skeletons) elegantes y altamente optimizados para tus aplicaciones.
🚀 Novedades en v2.0 #
Arquitectura Completamente Renovada #
- 🏗️ Patrón Provider: Sistema modular basado en providers especializados.
- 🎯 Detección Inteligente: Análisis automático de widgets con algoritmo de prioridades.
- 🔧 Extensibilidad: Fácil adición de nuevos tipos de widgets.
- 📦 Separación de Responsabilidades: Código más limpio y mantenible.
Optimizaciones de Rendimiento #
- ⚡ Sistema de Caché Avanzado: Reduce reconstrucciones.
- 🎨 RepaintBoundary Inteligente: Aislamiento de animaciones shimmer.
- 📏 LayoutBuilder Optimizado: Soluciona errores de viewport unbounded.
- 🔄 Lazy Loading: Generación bajo demanda de skeletons.
Configuración Global #
- ⚙️ SkeletonConfig: Configuración centralizada para toda la aplicación.
- 🔧 Builder Pattern: API fluida para configuración avanzada.
- 🎨 Temas Predefinidos dentro del builder: lightTheme, darkTheme, fastAnimation, slowAnimation.
- 🔄 Hot Reload Friendly: Cambios en tiempo real durante desarrollo.
Manejo de Errores Robusto #
- 🛡️ Error Boundaries: Fallbacks seguros para widgets complejos.
- 🔍 Validación Automática: Sanitización de dimensiones y propiedades.
- 📊 Logging Avanzado: Información detallada para debugging.
- 🔄 Recovery System: Recuperación automática de errores de layout.
✨ Características #
- 🚀 Implementación Zero-Config: Funciona automáticamente con un solo widget.
- 🎨 Personalización Avanzada: Colores, animaciones y transiciones configurables.
- 🔄 Soporte Universal: Compatible con todos los widgets de Flutter + widgets personalizados.
- ⚡ Performance: Sistema de caché y optimizaciones de renderizado.
- 🔧 Developer Experience: Hot reload, debugging tools y documentación completa.
🛠️ Configuración Global (Nuevo en v2.0) #
Configura una vez y aplica en toda tu aplicación:
void main() {
// Configuración global al inicio de la app
SkeletonConfig.configure(
defaultBaseColor: Colors.grey[300]!,
defaultHighlightColor: Colors.grey[100]!,
defaultShimmerDuration: Duration(milliseconds: 1200),
defaultTransitionDuration: Duration(milliseconds: 400),
);
runApp(MyApp());
}
Instalación #
Agrega la dependencia a tu archivo pubspec.yaml:
dependencies:
flutter_skeleton_loader: ^2.0.0
Luego ejecuta:
flutter pub get
🎯 Uso Básico #
Implementación Simple (Zero Config) #
import 'package:flutter/material.dart';
import 'package:flutter_skeleton_loader/flutter_skeleton_loader.dart';
class MyWidget extends StatefulWidget {
@override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
bool isLoading = true;
@override
void initState() {
super.initState();
_loadData();
}
Future<void> _loadData() async {
// Tu lógica de carga de datos
await Future.delayed(Duration(seconds: 2));
setState(() => isLoading = false);
}
@override
Widget build(BuildContext context) {
return SkeletonLoader(
isLoading: isLoading,
child: YourActualWidget(), // ✨ Automáticamente detecta y crea skeleton
);
}
}
API Builder Pattern (Nuevo en v2.0) #
Para configuraciones más avanzadas y API fluida:
SkeletonLoaderBuilder()
.child(ComplexWidget())
.loading(isLoading)
.lightTheme() // Aplica tema claro
.fastAnimation() // Animaciones rápidas
.build()
🔥 Ejemplos Avanzados #
Texto con Inteligencia de Longitud #
SkeletonLoader(
isLoading: isLoading,
child: Text(
'Este texto automáticamente determina el ancho del skeleton según su longitud',
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
),
)
Imagen con Detección de Dimensiones #
SkeletonLoader(
isLoading: isLoading,
child: Image.network(
'https://example.com/image.jpg',
width: 200,
height: 200,
fit: BoxFit.cover, // ✨ Skeleton respeta el BoxFit
),
)
Lista con Optimización de Performance #
SkeletonLoader(
isLoading: isLoading,
child: SizedBox(
height: 300,
child: ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage('https://picsum.photos/40'),
),
title: Text('Usuario $index'),
subtitle: Text('Descripción del usuario $index'),
trailing: Icon(Icons.chevron_right),
);
},
),
),
)
Formulario Complejo con Validación Visual #
SkeletonLoader(
isLoading: isLoading,
child: Form(
child: Column(
children: [
TextFormField(
decoration: InputDecoration(
labelText: 'Email',
prefixIcon: Icon(Icons.email),
),
),
SizedBox(height: 16),
TextFormField(
decoration: InputDecoration(
labelText: 'Contraseña',
prefixIcon: Icon(Icons.lock),
),
obscureText: true,
),
SizedBox(height: 20),
Row(
children: [
Checkbox(value: false, onChanged: null),
Text('Recordar credenciales'),
],
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {},
child: Text('Iniciar Sesión'),
),
],
),
),
)
Card Recursivo con Análisis de Hijos #
SkeletonLoader(
isLoading: isLoading,
child: Card(
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
CircleAvatar(radius: 24),
SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Juan Pérez', style: TextStyle(fontWeight: FontWeight.bold)),
Text('Desarrollador Flutter'),
],
),
),
IconButton(icon: Icon(Icons.more_vert), onPressed: null),
],
),
SizedBox(height: 12),
Image.network('https://picsum.photos/300/200'),
SizedBox(height: 12),
Text('Esta es una descripción del contenido de la card...'),
],
),
),
),
)
⚡ Optimizaciones de Performance #
Sistema de Caché Inteligente #
- ✅ El skeleton se genera UNA VEZ y se reutiliza
- ✅ Reduce reconstrucciones
- ✅ Caché basado en hash del widget y propiedades
SkeletonLoader(
isLoading: isLoading,
child: ExpensiveWidget(), // Solo se analiza una vez
)
RepaintBoundary Automático #
- ✅ Automáticamente aísla las animaciones shimmer.
- ✅ Evita repaints innecesarios del widget padre.
- ✅ Mejora significativamente el framerate.
Lazy Loading de Providers #
- ✅ Los providers se cargan solo cuando se necesitan.
- ✅ Startup time más rápido.
- ✅ Memoria optimizada.
Benchmark de Performance #
| Métrica | v1.x | v2.0 | Mejora |
|---|---|---|---|
| Widget Build Time | 12ms | 4ms | 🚀 3x más rápido |
| Memory Usage | 850KB | 340KB | 🚀 60% menos memoria |
| Cache Hit Rate | 0% | 78% | 🚀 Nuevo: caché inteligente |
| Smooth Animations | 45fps | 60fps | 🚀 RepaintBoundary |
🏗️ Arquitectura v2.0 #
Patrón Provider Modular #
// Cada tipo de widget tiene su provider especializado
interface SkeletonProvider {
bool canHandle(Widget widget);
int get priority;
Widget createSkeleton(Widget original, Color baseColor);
}
// Ejemplos de providers especializados:
TextSkeletonProvider // Analiza longitud de texto
ImageSkeletonProvider // Preserva aspect ratio
CardSkeletonProvider // Procesa children recursivamente
ListViewSkeletonProvider // Genera múltiples elementos
Registry Optimizado #
class OptimizedSkeletonRegistry {
// ✅ Caché de providers por tipo
// ✅ Lazy loading
// ✅ Fallback inteligente para tipos nuevos
}
🛠️ Guía de Migración de v1.x a v2.0 #
Cambios Automáticos (Sin Código) #
- ✅ API Backward Compatible: Tu código v1.x funciona sin cambios.
- ✅ Performance Automático: Todas las optimizaciones se aplican automáticamente.
- ✅ Mejor Detección: Skeletons más precisos sin cambiar tu código.
Nuevas Características Opcionales #
// v1.x (sigue funcionando)
SkeletonLoader(
isLoading: isLoading,
child: MyWidget(),
)
// v2.0 (configuración global recomendada)
void main() {
SkeletonConfig.configure(
defaultBaseColor: Color(0xFF424242),
defaultHighlightColor: Color(0xFF616161),
defaultShimmerDuration: Duration(milliseconds: 1000),
defaultTransitionDuration: Duration(milliseconds: 500),
); // ⭐ Nuevo
runApp(MyApp());
}
// v2.0 (builder pattern opcional)
SkeletonLoaderBuilder() // ⭐ Nuevo
.child(MyWidget())
.loading(isLoading)
.fastAnimation()
.build()
Problemas Solucionados Automáticamente #
- 🔧 "Horizontal viewport unbounded height" → Solucionado
- 🔧 "RenderBox was not laid out" → Solucionado
- 🔧 Card children not processed → Solucionado
- 🔧 Performance issues in lists → Solucionado
🎛️ Widgets Soportados (Detección Automática) #
Widgets de Texto y Contenido #
- ✅ Text - Análisis inteligente de longitud y estilo.
- ✅ Image - Detección de dimensiones y BoxFit.
- ✅ Icon - Preservación del tamaño original.
Widgets de Layout y Contenedores #
- ✅ Container - Análisis de decoración y dimensiones.
- ✅ SizedBox - Preservación exacta de dimensiones.
- ✅ Card - Procesamiento recursivo de hijos ⭐
- ✅ Padding - Respeto de padding original.
- ✅ Center - Mantenimiento de alineación.
Widgets de Listas y Navegación #
- ✅ ListView - Generación de elementos múltiples.
- ✅ PageView - Solución a errores unbounded ⭐
- ✅ ListTile - Detección de leading, title, subtitle, trailing.
- ✅ CircleAvatar - Preservación de radio y forma.
Widgets de Formularios #
- ✅ TextField - Detección de multilinea y decoración.
- ✅ TextFormField - Análisis de InputDecoration.
- ✅ Checkbox - Dimensiones estándar de Material.
- ✅ Switch - Forma ovalada característica.
- ✅ Radio - Soporte para tipos genéricos.
- ✅ DropdownButton - Cálculo inteligente de dimensiones ⭐.
- ✅ Slider - Respeto de dimensiones del track.
Widgets de Botones e Interacción #
- ✅ ElevatedButton - Análisis de contenido del botón.
- ✅ TextButton - Preservación de texto interno.
- ✅ IconButton - Cálculo de área de toque.
- ✅ FloatingActionButton - Forma circular característica.
- ✅ PopupMenuButton - Detección de icono y contenido.
Widgets de Layout Flexibles #
- ✅ Row - Análisis recursivo de children.
- ✅ Column - Procesamiento vertical inteligente.
- ✅ Wrap - Respeto de dirección de wrap.
- ✅ Flex - Análisis de dirección y children.
- ✅ Expanded - Preservación de flex.
- ✅ Flexible - Respeto de flex y fit.
Widgets Especializados #
- ✅ AppBar - Análisis de title, leading, actions.
- ✅ BottomNavigationBar - Múltiples items.
- ✅ TabBar - Análisis de tabs.
- ✅ Drawer - Contenido del drawer.
- ✅ SnackBar - Contenido del mensaje.
Sistema de Fallback Inteligente #
Para widgets no reconocidos, el sistema genera automáticamente un skeleton genérico que:
- 📏 Se adapta al tamaño del widget original
- 🎨 Aplica el estilo de skeleton configurado
- 🔄 Mantiene la estructura del layout padre
- ⚡ Optimiza el rendimiento con caché
🎨 Personalización Avanzada #
Configuración Básica #
SkeletonLoader(
isLoading: isLoading,
baseColor: Colors.grey[300]!, // Color base del skeleton
highlightColor: Colors.grey[100]!, // Color del shimmer
shimmerDuration: Duration(milliseconds: 1200), // Velocidad de animación
transitionDuration: Duration(milliseconds: 400), // Transición skeleton→contenido
child: YourWidget(),
)
Builder Pattern Avanzado #
SkeletonLoaderBuilder()
.child(ComplexWidget())
.loading(isLoading)
.baseColor(Colors.blue[200]!)
.highlightColor(Colors.blue[50]!)
.shimmerDuration(Duration(milliseconds: 800))
.transitionDuration(Duration(milliseconds: 300))
.build()
// O usando temas predefinidos
SkeletonLoaderBuilder()
.child(MyWidget())
.loading(isLoading)
.darkTheme() // Tema oscuro
.fastAnimation() // Animaciones rápidas
.build()
Configuración Global con Temas #
void main() {
// Configuración personalizada
SkeletonConfig.configure(
defaultBaseColor: Color(0xFF424242),
defaultHighlightColor: Color(0xFF616161),
defaultShimmerDuration: Duration(milliseconds: 1000),
defaultTransitionDuration: Duration(milliseconds: 500),
);
runApp(MyApp());
}
Temas Disponibles #
// Tema claro
SkeletonLoaderBuilder().lightTheme().build();
// Tema oscuro
SkeletonLoaderBuilder().darkTheme().build();
// Animaciones rápidas
SkeletonLoaderBuilder().fastAnimation().build();
// Animaciones suaves
SkeletonLoaderBuilder().slowAnimation().build();
🤝 Contribuir #
¡Las contribuciones son muy bienvenidas! La arquitectura v2.0 hace que agregar nuevos features sea más fácil que nunca.
Agregar Nuevo Widget Support #
- Crear un Provider:
class MyWidgetSkeletonProvider extends BaseSkeletonProvider {
@override
bool canHandle(Widget widget) => widget is MyWidget;
@override
int get priority => 7;
@override
Widget createSkeleton(Widget original, Color baseColor) {
// Tu lógica de skeleton aquí
}
}
- Registrar el Provider:
// En OptimizedSkeletonRegistry
providers.add(MyWidgetSkeletonProvider());
Áreas de Contribución Necesarias #
- 🆕 Nuevos Widget Providers: Material 3, Cupertino, custom widgets.
- 🎨 Temas Adicionales: Glassmorphism, Neumorphism, etc.
- ⚡ Optimizaciones: Cache strategies, memory optimizations.
- 📖 Documentación: Ejemplos, tutoriales, best practices.
Desarrollo Setup #
git clone https://github.com/idamkiller/flutter_skeleton_loader.git
cd flutter_skeleton_loader
flutter pub get
flutter test --coverage
Testing #
# Tests unitarios
flutter test
# Tests de integración
cd example && flutter test integration_test/
# Coverage report
genhtml coverage/lcov.info -o coverage/html
Si encuentras un bug o tienes una sugerencia, por favor abre un issue en GitHub con:
- 📱 Versión de Flutter
- 📦 Versión del paquete
- 🔍 Widget que causa problemas
- 🐛 Código de reproducción mínimo
📜 Licencia #
Este proyecto está licenciado bajo la Licencia MIT - ver el archivo LICENSE para más detalles.
Hecho con ❤️ por idamkiller
¿Te gusta este paquete? ¡Dale una ⭐ en GitHub y ayúdame a llegar a más desarrolladores!