Flutter Widget 之InheritedModel

669 阅读2分钟

如果您需要给一个深度潜入的Widget,访问存储在widget树顶部分的数据,InheritedModel是一个很好的方法。

您只需要建立您的子类,为您的数据添加一两个字段,并覆盖updateShouldNotify方法

class MyAncestor extends InheritedWidget {
    const MyAncestor(
        this.colorOne,
        this.colorTwo,
        Widget child,
    ): super(child: child);

    final Color colorOne,
    final Color colorTwo,

    @override
    bool updateShouldNotify(
        MyAncestor oldWidget) {
        return colorOne != oldWidget.colorOne ||
            colorTwo != oldWidget.colorTwo;
    }
}

如果替换了InheritedWidget,这决定了依赖的widget是否应该rebuild。

子代项目集合可以从他们的build方法中从你的widget集成。

class ColorOneWidget extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        final ancestor = context
            .inheritFromWidgetOfExactType(
            MyAncestor);
        return Container(
            color: ancestor.colorOne,
            height: 50.0,
            widget: 50.0,
        );
    }
}

class ColorTwoWidget extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        final ancestor = context
            .inheritFromWidgetOfExactType(
            MyAncestor);
        return Container(
            color: ancestor.colorTwo,
            height: 50.0,
            widget: 50.0,
        );
    }
}

之后让它运行。

如果替换了InheritedWidget, updateSholdNotify就会开始,并决定是否立刻reuild子代合集。

但是如果那些widget rebuild费用高怎么办呢?

如果他们可以依赖于祖系项目数据的特定部分,而不是整个widget,那不是很好吗?

应对这个,我们有InheritedModel的运作方式一样,但是当子代项目集合从中继承

class MyAncestor extends InheritedModel<String> {
    const MyAncestor(
        this.colorOne,
        this.colorTwo,
        Widget child,
    ): super(child: child);

    final Color colorOne,
    final Color colorTwo,

    @override
    bool updateShouldNotify(
        MyAncestor oldWidget ) {
        return colorOne != oldWidget.colorOne ||
            colorTwo != oldWidget.colorTwo;
    }
}

class ColorOneWidget extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        final ancestor = InheritedModel
            .inheritFrom<MyANcestor>(
            context,
            aspect: 'one',
         );
        return Container(
            color: ancestor.colorOne,
            height: 50.0,
            widget: 50.0,
        );
    }
}

他们就会提供一个参数来指示他们所关心的字段和InheritedModel有一个名为updateShouldNotifyDependent的覆盖方法,来决定哪个widget是否需要rebuild。

class MyAncestor extends InheritedModel<String> {
    ...

    @override
    bool updateShouldNotify(
        MyAncestor oldWidget,
        Set<String> dependenices) {
        if (dependencies.contains('one') &&
            colorOne != oldWidget.colorOne) {
            return true;
        }
        if (dependencies.contains('two') && 
            colorTwo != oldWidget.colorWidget) {
            return true;
        }
        return false;
    }
}

所以你继承一个model 可以确认那个widget的方面 并传回true命令来rebuild或false命令来保持指令的现有状态。

所以无论widget是否需要存储两种颜色或是一打即时网络连接,InheritedModel都能在您需要的时候帮助你rebuild它的子代项目集合。

如果想了解有关InheritedModel的内容,或者关于Flutter的其他功能,请访问flutter.io

原文翻译自视频:视频地址