indexd_stack_dev 0.1.3 copy "indexd_stack_dev: ^0.1.3" to clipboard
indexd_stack_dev: ^0.1.3 copied to clipboard

A high-performance lazy-loading IndexedStack for Flutter that initializes pages only when needed.

indexd_stack_dev #

A high-performance lazy-loading IndexedStack for Flutter with a custom RenderObject pipeline and native tab transitions. Pages are initialized only when accessed, and inactive tabs consume zero layout or paint resources.

Features #

  • ๐Ÿš€ Custom RenderObject: Only the active child participates in layout โ€” inactive cached pages are completely skipped
  • โšก Native Animations: Fade, FadeThrough, SharedAxis transitions built without external dependencies
  • ๐Ÿ’พ LRU Cache: Configurable maxCachedPages with automatic least-recently-used eviction
  • ๐Ÿงน Memory Pressure: Automatic cache flush on OS memory warnings via WidgetsBindingObserver
  • ๐Ÿ”„ TickerMode: Animations in background tabs are automatically paused
  • ๐ŸŽฏ Zero Overhead: When animation: IndexdAnimationType.none, no AnimationController is allocated

Installation #

dependencies:
  indexd_stack_dev: ^0.1.0
flutter pub get

Quick Start #

import 'package:indexd_stack_dev/indexd_stack_dev.dart';

class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  late LazyStackController controller;
  
  @override
  void initState() {
    super.initState();
    controller = LazyStackController(
      initialIndex: 0,
      maxCachedPages: 3,
      disposeUnused: true,
      isListenMemoryPressure: true,
    );
  }
  
  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: LazyLoadIndexedStack(
        controller: controller,
        animation: IndexdAnimationType.fadeThrough, // or .none for zero overhead
        children: [
          HomePage(),
          ProfilePage(),
          SettingsPage(),
        ],
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: controller.currentIndex,
        onTap: (index) => controller.switchTo(index, 3),
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
          BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
          BottomNavigationBarItem(icon: Icon(Icons.settings), label: 'Settings'),
        ],
      ),
    );
  }
}

Animations #

Pass IndexdAnimationType to control tab transitions:

LazyLoadIndexedStack(
  controller: controller,
  animation: IndexdAnimationType.sharedAxisHorizontal,
  animationDuration: const Duration(milliseconds: 300),
  children: [...],
)
Type Description
none Instant switch, zero allocation (default)
fade Simple crossfade
fadeThrough Material Design fade through (scale + fade)
sharedAxisHorizontal Slide + fade on the X axis
sharedAxisVertical Slide + fade on the Y axis

Animation type can be changed dynamically at runtime. Switching to none immediately disposes the AnimationController.

API Reference #

LazyStackController #

LazyStackController({
  int initialIndex = 0,
  List<int> preloadIndexes = const [],
  bool disposeUnused = false,
  int maxCachedPages = 3,
  bool isListenMemoryPressure = false,
})
Property Type Description
currentIndex int Currently visible page
loadedIndexes Set<int> Pages currently in memory
canGoBack bool Whether current index > 0
Method Description
switchTo(index, totalPages) Switch to a page with automatic cache management
disposePage(index) Remove a specific page from memory
disposePages(indexes) Remove multiple pages from memory
reset() Clear all pages except current and preloaded
preloadPage(index, totalPages) Eagerly load a page into cache
preloadAdjacentPages(totalPages, [range]) Preload pages adjacent to current
isLoaded(index) Check if a page is in memory
didHaveMemoryPressure() Manually trigger memory flush

LazyLoadIndexedStack #

LazyLoadIndexedStack({
  required LazyStackController controller,
  required List<Widget> children,
  IndexdAnimationType animation = IndexdAnimationType.none,
  Duration animationDuration = const Duration(milliseconds: 300),
  AlignmentGeometry alignment = AlignmentDirectional.topStart,
  TextDirection? textDirection,
})

Architecture #

LazyLoadIndexedStack (StatefulWidget)
  โ””โ”€โ”€ AnimationController? (null when animation == none)
  โ””โ”€โ”€ _LazyRenderStack (MultiChildRenderObjectWidget)
       โ””โ”€โ”€ _RenderLazyStack (RenderBox)
            โ”œโ”€โ”€ performLayout: only active + transitioning child
            โ”œโ”€โ”€ paint: outgoing first, incoming on top
            โ””โ”€โ”€ hitTest: only active child receives touches

License #

MIT

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

1
likes
0
points
137
downloads

Publisher

unverified uploader

Weekly Downloads

A high-performance lazy-loading IndexedStack for Flutter that initializes pages only when needed.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter

More

Packages that depend on indexd_stack_dev