Skip to content

Fharhanamrin/flutter-widget-lifecycle

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Flutter Widget Lifecycle & Performance — Interactive Learning App

A hands-on Flutter application designed as a deep-dive learning resource for understanding StatefulWidget lifecycle, ListView lazy rendering behavior, and resource cleanup patterns in Flutter.

Built as part of my Flutter fundamentals learning path, this project turns abstract lifecycle concepts into interactive, observable demos with real-time console logging.


What You'll Learn

  • StatefulWidget Lifecycle — the complete sequence from createState() to dispose(), observed in real-time through 5 interactive scenarios
  • ListView Lazy Rendering — how Flutter creates and destroys widgets on scroll, and why didChangeDependencies() fires when you don't expect it
  • Resource Cleanup Patterns — when to use dispose(), if (!mounted) return, and CancelableOperation to prevent memory leaks and crashes
  • copyWith Pattern — why immutable models matter and how copyWith enables clean state updates in Bloc/Cubit/Riverpod

Interactive Demos

1. Widget Lifecycle Demo

Five scenarios that let you observe each lifecycle method in action:

Scenario What You Observe
First Mount createState → initState → didChangeDependencies → build
setState Only build() is called — not initState or didChangeDependencies
didUpdateWidget Parent passes new props → didUpdateWidget → build, state preserved
didChangeDependencies Toggle theme (InheritedWidget) → triggers didChangeDependencies
dispose Hide/show widget → full deactivate → dispose and fresh creation cycle

2. ListView Deep Dive

Four tabs comparing different rendering strategies:

Tab Behavior
ListView (Lazy) Scroll out = dispose, scroll back = recreate from scratch (state lost)
KeepAlive Same ListView but with AutomaticKeepAliveClientMixin — state preserved
SCSV + Column SingleChildScrollView + Column — all widgets stay alive, no lifecycle on scroll
ListView.separated ListView.separated with automatic dividers between items

3. Counter (Provider + Repository)

Simple counter demonstrating layered architecture: UI → Provider → Repository → Model.


Project Architecture

lib/
├── main.dart                          # Entry point
├── app.dart                           # MaterialApp + navigation menu
├── core/
│   ├── constants/app_constants.dart    # App-wide constants
│   └── theme/app_theme.dart           # Light & dark theme config
├── data/
│   ├── models/counter_model.dart      # Data model
│   └── repositories/counter_repository.dart
├── providers/
│   └── counter_provider.dart          # ChangeNotifier for counter
└── ui/
    ├── screens/
    │   ├── home/                      # Counter demo screen
    │   ├── lifecycle/                 # Widget lifecycle demo
    │   └── listview/                  # ListView deep dive demo
    └── shared/
        └── custom_button.dart

Documentation

Comprehensive Bahasa Indonesia documentation covering theory, diagrams, and practical examples:

Document Topics Covered
docs/struktur-project/README.md Project structure & layered architecture
docs/struktur-project/widget-lifecycle.md Complete StatefulWidget lifecycle guide with 5 scenario walkthroughs
docs/list-view/penjelasan.md ListView internals: lazy rendering, cacheExtent, pagination, memory optimization
docs/performance/penjelasan.md Resource cleanup: dispose patterns, mounted guard, 6 real-world cleanup cases
docs/performance/Penjelasan-copywith.md copyWith pattern: immutable models, state management, memory visualization

Getting Started

Prerequisites

  • Flutter SDK >=3.11.1
  • Dart SDK (included with Flutter)

Run the App

# Clone the repository
git clone https://github.com/your-username/flutter-widget-lifecycle.git

# Navigate to project directory
cd flutter-widget-lifecycle

# Install dependencies
flutter pub get

# Run on your device or emulator
flutter run

How to Use

  1. Open the app — you'll see the main menu with three demo options
  2. Select Widget Lifecycle Demo — interact with each scenario and watch the console output
  3. Select ListView Deep Dive — tap +1 on items, scroll away, scroll back, and compare behavior across tabs
  4. Keep the Debug Console open to see real-time lifecycle logs with timestamps

Key Takeaways

ListView is lazy — it only renders what's visible. Widgets that scroll off-screen get dispose()d and are recreated from scratch when scrolling back. This is memory-efficient for large lists, but means widget state is lost unless you use AutomaticKeepAliveClientMixin or hold data in a parent state.

Always clean up resources — every StreamSubscription, AnimationController, TextEditingController, FocusNode, ScrollController, and Timer created in initState() must be disposed in dispose(). For async operations, guard with if (!mounted) return before calling setState().

Data belongs in the parent, not in list items — ListView is just a renderer. Store data in parent state or state management (Provider, Bloc, Riverpod) so scrolling doesn't trigger unnecessary API calls.


Tech Stack

  • Flutter 3.11+
  • Dart 3.11+
  • Provider 6.1 — state management for counter demo
  • Material 3 — modern UI components

License

This project is open-source and available for learning purposes. Feel free to fork, study, and build upon it.


Built with the goal of making Flutter's internal mechanics visible and interactive — because the best way to learn lifecycle is to watch it happen in real-time.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors