Виджет InheritedModel
Виджет InheritedModel расширяет
InheritedWidget
и делит данные на аспекты. Потомки зависят от части полей,
а updateShouldNotifyDependent
решает, кого перестроить при смене аспекта.
Синтаксис
InheritedModel(
child: child,
)
Параметры
| Параметр | Описание |
|---|---|
child |
Поддерево, которое читает модель через аспекты. |
key |
Необязательный ключ виджета. |
Методы
| Метод | Описание |
|---|---|
updateShouldNotifyDependent |
Сравнивает аспект и решает, уведомлять ли зависимого. |
Пример
Давайте разделим title и count по аспектам:
import 'package:flutter/material.dart';
void main()
{
runApp(
MaterialApp(
home: PairModel(
title: 'abcde',
count: 1,
child: Scaffold(
body: Center(
child: TitleOnly(),
),
),
),
),
);
}
enum PairAspect { title, count }
class PairModel extends InheritedModel<PairAspect>
{
const PairModel({super.key, required this.title, required this.count, required super.child});
final String title;
final int count;
static PairModel of(BuildContext context, PairAspect aspect) {
return InheritedModel.inheritFrom<PairModel, PairAspect>(context, aspect: aspect)!;
}
@override
bool updateShouldNotify(PairModel oldWidget) {
return title != oldWidget.title || count != oldWidget.count;
}
@override
bool updateShouldNotifyDependent(PairModel oldWidget, Set<PairAspect> dependencies) {
if (dependencies.contains(PairAspect.title) && title != oldWidget.title) {
return true;
}
if (dependencies.contains(PairAspect.count) && count != oldWidget.count) {
return true;
}
return false;
}
}
class TitleOnly extends StatelessWidget
{
const TitleOnly({super.key});
@override
Widget build(BuildContext context)
{
final model = PairModel.of(context, PairAspect.title);
return Text(model.title);
}
}
На экране TitleOnly покажет 'abcde', завися только от аспекта title.
Пример
Давайте изменим count, не трогая title на экране title:
import 'package:flutter/material.dart';
void main()
{
runApp(const MaterialApp(home: AspectHost()));
}
enum PairAspect { title, count }
class PairModel extends InheritedModel<PairAspect>
{
const PairModel({super.key, required this.title, required this.count, required super.child});
final String title;
final int count;
static PairModel of(BuildContext context, PairAspect aspect) {
return InheritedModel.inheritFrom<PairModel, PairAspect>(context, aspect: aspect)!;
}
@override
bool updateShouldNotify(PairModel oldWidget) {
return title != oldWidget.title || count != oldWidget.count;
}
@override
bool updateShouldNotifyDependent(PairModel oldWidget, Set<PairAspect> dependencies) {
if (dependencies.contains(PairAspect.title) && title != oldWidget.title) {
return true;
}
if (dependencies.contains(PairAspect.count) && count != oldWidget.count) {
return true;
}
return false;
}
}
class TitleOnly extends StatelessWidget
{
const TitleOnly({super.key});
@override
Widget build(BuildContext context)
{
final model = PairModel.of(context, PairAspect.title);
return Text(model.title);
}
}
class AspectHost extends StatefulWidget
{
const AspectHost({super.key});
@override
State<AspectHost> createState() => _AspectHostState();
}
class _AspectHostState extends State<AspectHost>
{
var title = 'abcde';
var count = 0;
@override
Widget build(BuildContext context)
{
return PairModel(
title: title,
count: count,
child: Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const TitleOnly(),
ElevatedButton(
onPressed: () => setState(() => count++),
child: Text('12345 $count'),
),
],
),
),
),
);
}
}
На экране рост count не меняет строку title благодаря аспектам.
Смотрите также
-
метод
updateShouldNotifyDependent,
который фильтрует уведомления -
виджет
InheritedWidget,
базовый класс дляInheritedModel -
метод
updateShouldNotify,
который уведомляет всех зависимых -
класс
BuildContext,
через который регистрируют аспект