smart_image_x 1.0.2
smart_image_x: ^1.0.2 copied to clipboard
One widget that auto-detects any image source (network, asset, file, bytes, base64, SVG) with caching, BlurHash, zoom, galleries and transformations.
import 'package:flutter/material.dart';
import 'package:smart_image_x/smart_image_x.dart';
import 'pages/cache_page.dart';
import 'pages/features_page.dart';
import 'pages/gallery_page.dart';
import 'pages/sources_page.dart';
import 'pages/tools_page.dart';
void main() {
// Optional one-time configuration (everything works without it).
SmartImageConfig.configure(
const SmartImageConfig(
cache: CacheConfig(maxMemoryBytes: 64 * 1024 * 1024),
defaultRetry: RetryConfig(maxAttempts: 3),
defaultLoaderType: LoaderType.shimmer,
logLevel: SmartImageLogLevel.warning,
),
);
runApp(const SmartImageXDemo());
}
/// Root of the SmartImageX showcase app.
class SmartImageXDemo extends StatefulWidget {
const SmartImageXDemo({super.key});
@override
State<SmartImageXDemo> createState() => _SmartImageXDemoState();
}
class _SmartImageXDemoState extends State<SmartImageXDemo> {
ThemeMode _themeMode = ThemeMode.light;
void _toggleTheme() {
setState(() {
_themeMode =
_themeMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light;
});
}
ThemeData _theme(Brightness brightness) {
return ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF6750A4),
brightness: brightness,
),
useMaterial3: true,
cardTheme: CardThemeData(
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(18),
side: BorderSide(
color: brightness == Brightness.light
? const Color(0x14000000)
: const Color(0x1FFFFFFF),
),
),
),
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'SmartImageX',
debugShowCheckedModeBanner: false,
themeMode: _themeMode,
theme: _theme(Brightness.light),
darkTheme: _theme(Brightness.dark),
home: HomeShell(
isDark: _themeMode == ThemeMode.dark,
onToggleTheme: _toggleTheme,
),
);
}
}
/// The home scaffold: an app bar with a theme toggle and a bottom
/// [NavigationBar] across the five demo sections.
class HomeShell extends StatefulWidget {
const HomeShell({
required this.isDark,
required this.onToggleTheme,
super.key,
});
final bool isDark;
final VoidCallback onToggleTheme;
@override
State<HomeShell> createState() => _HomeShellState();
}
class _HomeShellState extends State<HomeShell> {
int _index = 0;
static const _pages = [
SourcesPage(),
FeaturesPage(),
GalleryPage(),
ToolsPage(),
CachePage(),
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
titleSpacing: 16,
title: Row(
children: [
const SmartImage(image: 'assets/logo.svg', width: 28, height: 28),
const SizedBox(width: 10),
Text.rich(
TextSpan(
children: [
const TextSpan(
text: 'SmartImage',
style: TextStyle(fontWeight: FontWeight.w700),
),
TextSpan(
text: 'X',
style: TextStyle(
fontWeight: FontWeight.w700,
color: Theme.of(context).colorScheme.primary,
),
),
],
),
),
],
),
actions: [
IconButton(
tooltip: widget.isDark ? 'Light theme' : 'Dark theme',
onPressed: widget.onToggleTheme,
icon: Icon(widget.isDark ? Icons.light_mode : Icons.dark_mode),
),
const SizedBox(width: 4),
],
),
body: AnimatedSwitcher(
duration: const Duration(milliseconds: 250),
child: KeyedSubtree(
key: ValueKey(_index),
child: _pages[_index],
),
),
bottomNavigationBar: NavigationBar(
selectedIndex: _index,
onDestinationSelected: (i) => setState(() => _index = i),
destinations: const [
NavigationDestination(
icon: Icon(Icons.collections_outlined),
selectedIcon: Icon(Icons.collections),
label: 'Sources',
),
NavigationDestination(
icon: Icon(Icons.auto_awesome_outlined),
selectedIcon: Icon(Icons.auto_awesome),
label: 'Features',
),
NavigationDestination(
icon: Icon(Icons.photo_library_outlined),
selectedIcon: Icon(Icons.photo_library),
label: 'Gallery',
),
NavigationDestination(
icon: Icon(Icons.build_outlined),
selectedIcon: Icon(Icons.build),
label: 'Tools',
),
NavigationDestination(
icon: Icon(Icons.storage_outlined),
selectedIcon: Icon(Icons.storage),
label: 'Cache',
),
],
),
);
}
}