日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

flutter?InheritedWidget使用方法總結(jié)_Android

作者:李小轟_Rex ? 更新時(shí)間: 2022-12-12 編程語言

引言

InheritedWidget,flutter中非常重要的一個(gè)功能組件。比如我們在應(yīng)用的根 widget 中通過InheritedWidget共享了一個(gè)數(shù)據(jù),那么我們便可以在任意子 widget 中來獲取該共享的數(shù)據(jù)。

didChangeDependencies

說到 InheritedWidget ,我們不得不聊聊 state 對象中的 didChangeDependencies 方法。當(dāng)子控件依賴使用了父控件中的 InheritedWidget,比如主題、locale(語言)等發(fā)生變化時(shí),依賴其的子 widget 的didChangeDependencies方法將會被調(diào)用。

一般來說,子 widget 很少會重寫此方法,因?yàn)樵谝蕾嚫淖兒?framework 也都會調(diào)用build()方法。但是,如果你需要在依賴改變后執(zhí)行一些昂貴的操作,比如網(wǎng)絡(luò)請求,這時(shí)最好的方式就是在此方法中執(zhí)行,這樣可以避免每次build()都執(zhí)行這些昂貴操作。

重點(diǎn): 如子控件build 方法中沒有使用 InheritedShareWidget 的數(shù)據(jù),那么它的didChangeDependencies將不會被調(diào)用

如何使用?

我們簡單用一個(gè) count 自增的例子來記錄 InheritedWidget 的使用:

  • 新建 InheritedShareWidget 繼承 InheritedWidget 作為共享數(shù)據(jù)源,以其為父節(jié)點(diǎn)提供子節(jié)點(diǎn)數(shù)據(jù)
import 'package:flutter/material.dart';
class InheritedShareWidget extends InheritedWidget {
  //用于共享的數(shù)據(jù)
  final int data;
  InheritedShareWidget({this.data, Widget child}) : super(child: child);
  //定義便捷方法,方便子控件獲取共享數(shù)據(jù)
  static InheritedShareWidget of(BuildContext context) {
    ///當(dāng)子控件依賴使用了我們的數(shù)據(jù)源時(shí),數(shù)據(jù)變動會觸發(fā)子控件中的 didChangeDependencies 方法
    return context.dependOnInheritedWidgetOfExactType<InheritedShareWidget>();
    ///(前提:子控件使用了數(shù)據(jù)源)子控件中的 didChangeDependencies 方法不會被觸發(fā)
    // return context.getElementForInheritedWidgetOfExactType<InheritedShareWidget>().widget;
  }
  @override
  bool updateShouldNotify(covariant InheritedShareWidget oldWidget) {
    //返回true時(shí),才會通知子控件
    return oldWidget.data != this.data;
  }
}

注意:updateShouldNotify方法中,通知指的是通知子控件的didChangeDependencies 方法,前提是子控件使用dependOnInheritedWidgetOfExactType 的方式獲取共享數(shù)據(jù)。

  • 子節(jié)點(diǎn)中如何獲取共享數(shù)據(jù)?
class TestShareChildWidget extends StatefulWidget {
  const TestShareChildWidget({Key key}) : super(key: key);
  @override
  _TestShareChildWidgetState createState() => _TestShareChildWidgetState();
}
class _TestShareChildWidgetState extends State<TestShareChildWidget> {
  @override
  void didChangeDependencies() {
    ///如build 方法中沒有使用 InheritedShareWidget 的數(shù)據(jù),那么它的didChangeDependencies()將不會被調(diào)用
    super.didChangeDependencies();
    print("enter didChangeDependencies");
  }
  @override
  Widget build(BuildContext context) {
    print("enter child build");
    //獲取Inherited的共享數(shù)據(jù):
    final data = InheritedShareWidget.of(context).data.toString();
    return Text(data);
  }
}
  • 兩者通過父子嵌套的關(guān)系聯(lián)系在一起:
class _TestInheritedWidgetState extends State<TestInheritedWidget> {
  int count = 0;
  @override
  Widget build(BuildContext context) {
    return Center(
      child: InheritedShareWidget(
        data: count,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            TestShareChildWidget(),
            RaisedButton(
                child: Text('add'),
                onPressed: () {
                  setState(() {
                    ++count;
                  });
                })
          ],
        ),
      ),
    );
  }
}

大家注意到,demo中操作++count時(shí),使用了setState手動觸發(fā)控件進(jìn)行刷新。

結(jié)論

InheritedWidget只提供我們共享數(shù)據(jù)的能力,以及控制是否在 build 前觸發(fā)didChangeDependencies 的能力。不會主動觸發(fā)build方法,如果build沒被觸發(fā),那么didChangeDependencies 也不會被觸發(fā)。

號外擴(kuò)展

InheritedWidget 數(shù)據(jù)共享能力不會受到 Navigator push 新頁面的影響,與原生不一樣,flutter的頁面跳轉(zhuǎn)不是管理一個(gè)堆棧,Navigator 本質(zhì)上是使用 overlay 管理一個(gè) stack widget,因此 InheritedWidget 基于父子關(guān)系管理的數(shù)據(jù)共享?xiàng)l件沒有被打破

原文鏈接:https://juejin.cn/post/7007676491605475358

欄目分類
最近更新