Ответ
ProxyWidget — это абстрактный класс-помощник в Flutter, который служит основой для виджетов, чья основная роль — обернуть, модифицировать или предоставить данные (InheritedWidget) другим виджетам, без принудительного перестроения этих дочерних виджетов при обновлении самого прокси. Это инструмент для оптимизации производительности.
Основная идея: ProxyWidget принимает child (или children) в конструкторе и перестраивает только себя при изменениях, в то время как дочерний виджет может оставаться прежним экземпляром, сохраняя свое состояние.
Иерархия и основные подклассы:
ProxyWidget(абстрактный)ParentDataWidget(например,Positioned,Flexible)InheritedWidget(основа для передачи данных по дереву)RenderObjectWidgetопределенных типов
Практический пример: создание простого InheritedWidget-прокси
class MyThemeProxy extends InheritedWidget {
final Color primaryColor;
const MyThemeProxy({
Key? key,
required this.primaryColor,
required Widget child,
}) : super(key: key, child: child);
@override
bool updateShouldNotify(MyThemeProxy oldWidget) {
// Дочерние виджеты, зависящие от этого, перестроятся,
// только если изменился primaryColor.
return primaryColor != oldWidget.primaryColor;
}
static MyThemeProxy? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<MyThemeProxy>();
}
}
// Использование:
MyThemeProxy(
primaryColor: Colors.blue,
child: MyApp(), // Это дерево виджетов получит доступ к primaryColor через MyThemeProxy.of(context)
)
Зачем это нужно?
- Оптимизация: Если
MyThemeProxyперестраивается с новымprimaryColor, ноchild(все приложение) остается тем же объектом, Flutter не будет перестраивать все гигантское дерево заново. Оно получит уведомление черезupdateShouldNotifyи перестроит только те виджеты, которые явно зависят отprimaryColor(вызвалиof(context)). - Сохранение состояния: Сложное состояние (например,
TextEditingControllerв дочернемTextField) не сбрасывается, потому что виджет-обертка (TextField) не пересоздается.
Вывод: ProxyWidget и его наследники — это фундаментальный механизм Flutter для эффективного обновления UI, позволяющий избежать каскадных перестроений всего дерева виджетов при изменении данных или конфигурации где-то на верхнем уровне.