skills/flutter/references/features-inherited-widget.md

3.1 KiB

name description
features-inherited-widget Flutter InheritedWidget - sharing data down the widget tree, theme access, and InheritedWidget patterns

InheritedWidget

InheritedWidget efficiently shares data down the widget tree.

Basic InheritedWidget

class CounterInherited extends InheritedWidget {
  final int count;
  final VoidCallback increment;

  const CounterInherited({
    super.key,
    required this.count,
    required this.increment,
    required super.child,
  });

  static CounterInherited? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<CounterInherited>();
  }

  @override
  bool updateShouldNotify(CounterInherited oldWidget) {
    return count != oldWidget.count;
  }
}

Using InheritedWidget

CounterInherited(
  count: _count,
  increment: _increment,
  child: MyApp(),
)

// Access in descendant
class CounterDisplay extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final counter = CounterInherited.of(context);
    return Text('Count: ${counter?.count ?? 0}');
  }
}

updateShouldNotify

Control when descendants rebuild.

@override
bool updateShouldNotify(CounterInherited oldWidget) {
  // Only rebuild if count changed
  return count != oldWidget.count;
}

dependOnInheritedWidgetOfExactType

Register dependency and rebuild when widget changes.

static CounterInherited? of(BuildContext context) {
  return context.dependOnInheritedWidgetOfExactType<CounterInherited>();
}

getElementForInheritedWidgetOfExactType

Access without registering dependency.

static CounterInherited? of(BuildContext context) {
  final element = context.getElementForInheritedWidgetOfExactType<CounterInherited>();
  return element?.widget as CounterInherited?;
}

Complete Example

class ThemeInherited extends InheritedWidget {
  final ThemeData theme;
  final VoidCallback toggleTheme;

  const ThemeInherited({
    super.key,
    required this.theme,
    required this.toggleTheme,
    required super.child,
  });

  static ThemeInherited? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<ThemeInherited>();
  }

  @override
  bool updateShouldNotify(ThemeInherited oldWidget) {
    return theme != oldWidget.theme;
  }
}

// Usage
ThemeInherited(
  theme: _theme,
  toggleTheme: _toggleTheme,
  child: MaterialApp(...),
)

// Access
final theme = ThemeInherited.of(context)?.theme;

Key Points

  • Use InheritedWidget to share data down the tree
  • Implement updateShouldNotify() to control rebuilds
  • Use dependOnInheritedWidgetOfExactType() to register dependency
  • Use getElementForInheritedWidgetOfExactType() to access without dependency
  • More efficient than passing data through constructors
  • Used by Theme, MediaQuery, Localizations
  • Only rebuilds descendants when data changes