Ответ
InheritedWidget — это специальный виджет в Flutter, предназначенный для эффективной передачи данных вниз по дереву виджетов. Он позволяет дочерним виджетам получать доступ к данным без необходимости явно прокидывать их через конструкторы каждого промежуточного виджета (проброс пропсов).
Ключевые особенности:
- Эффективность: При изменении данных в
InheritedWidgetFlutter перестраивает только те виджеты, которые от этих данных зависят (вызвалиcontext.dependOnInheritedWidgetOfExactType), а не всё поддерево. - Доступность: Любой виджет в поддереве ниже
InheritedWidgetможет получить к нему доступ. - Использование: Исторически использовался для тем, локализации, аутентификации или любого другого «глобального» для поддерева состояния.
Пример реализации и использования:
// 1. Создаем InheritedWidget
class AppTheme extends InheritedWidget {
final Color primaryColor;
final Brightness brightness;
const AppTheme({
required this.primaryColor,
required this.brightness,
required Widget child,
Key? key,
}) : super(key: key, child: child);
// 2. Статический метод для удобного доступа
static AppTheme of(BuildContext context) {
final AppTheme? result = context.dependOnInheritedWidgetOfExactType<AppTheme>();
assert(result != null, 'No AppTheme found in context');
return result!;
}
// 3. Метод, определяющий, нужно ли уведомлять зависимые виджеты об обновлении
@override
bool updateShouldNotify(AppTheme oldWidget) {
return primaryColor != oldWidget.primaryColor || brightness != oldWidget.brightness;
}
}
// 4. Использование в дочернем виджете
class ThemedButton extends StatelessWidget {
const ThemedButton({super.key});
@override
Widget build(BuildContext context) {
// Получаем данные из ближайшего AppTheme в дереве
final theme = AppTheme.of(context);
return ElevatedButton(
style: ElevatedButton.styleFrom(primary: theme.primaryColor),
onPressed: () {},
child: const Text('Кнопка'),
);
}
}
Важно: InheritedWidget — это низкоуровневый примитив. В современных приложениях для управления состоянием чаще используются пакеты-надстройки, такие как Provider (который сам построен на InheritedWidget), Riverpod или Bloc, так как они предоставляют более удобный API и лучшие возможности для тестирования.