Flutter:InheritedWidget数据共享

未使用数据共享时,要传递数据,只能组件间一级一级向下传递

下边代码中,创建了一个按钮,当点击时_count++

并将数据通过Test1(count)传递给Test2(count),最终传递给Test3(count)进行渲染展示。

js 复制代码
import 'package:flutter/material.dart';

class Demo extends StatefulWidget {
  @override
  State<Demo> createState() => _DemoState();
}

class _DemoState extends State<Demo> {
  int _count = 0;
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Test1(_count),
        ElevatedButton(onPressed: (){
          _count++;
          setState(() {});
        }, child: Text('我是按钮'))
      ],
    )
  }
}

class Test1 extends StatelessWidget {
  final int count;
  Test1(this.count);
  @override
  Widget build(BuildContext context) {
    return Test2(count);
  }
}


class Test2 extends StatelessWidget {
  final int count;
  Test2(this.count);
  @override
  Widget build(BuildContext context) {
    return Test3(count);
  }
}

class Test3 extends StatefulWidget {
  final int count;
  Test3(this.count);
  @override
  State<Test3> createState() => _Test3State();
}

class _Test3State extends State<Test3> {

  @override
  Widget build(BuildContext context) {
    return Text(widget.count.toString());
  }
}

InheritedWidget数据共享,优化下上边代码

js 复制代码
import 'package:flutter/material.dart';

// 声明MyData类 继承 InheritedWidget
class MyData extends InheritedWidget{
  // 在子组件中需要共享的数据
  final int data;
  // 构造方法
  const MyData({required this.data, child}):super(child: child);
  // 对外提供方法,方便在子组件中获取共享的数据
  static MyData? of(BuildContext context){
    return context.dependOnInheritedWidgetOfExactType<MyData>();
  }
  // 该回调决定当前data发生变化的时候,是否通知子组件依赖data的Widget:子组件中只有使用了MyData.of(context)!.data 的才会产生依赖关系
  @override
  bool updateShouldNotify(covariant MyData oldWidget) {
    // 如果旧的data不等于新的data,返回true,子组件依赖data的Widget(就看子组件build中是否使用了MyData.of(context)!.data):就会触发生命周期:didChangeDependencies
    // 如果return false; 则不会触发:didChangeDependencies
    return oldWidget.data != data;
  }
}

class Demo extends StatefulWidget {
  @override
  State<Demo> createState() => _DemoState();
}

class _DemoState extends State<Demo> {
  int _count = 0;
  @override
  Widget build(BuildContext context) {
    // MyData在Widget树中必须是根,MyData里边的数据才能产生共享
    return MyData(data: _count,child: Column(
      children: [
        SizedBox(height: 100,),
        Test1(_count),
        ElevatedButton(onPressed: (){
          _count++;
          setState(() {});
        }, child: Text('我是按钮'))
      ],
    ),);
  }
}

class Test1 extends StatelessWidget {
  final int count;
  Test1(this.count);
  @override
  Widget build(BuildContext context) {
    return Test2(count);
  }
}


class Test2 extends StatelessWidget {
  final int count;
  Test2(this.count);
  @override
  Widget build(BuildContext context) {
    return Test3(count);
  }
}

class Test3 extends StatefulWidget {
  final int count;
  Test3(this.count);
  @override
  State<Test3> createState() => _Test3State();
}

class _Test3State extends State<Test3> {

  @override
  void didChangeDependencies() {
    // 如果有很多逻辑依赖这个数据,可以在这里进行保存
    print('didChangeDependencies:调用了');
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    // return Text(widget.count.toString());
    print('当数据发生变化,build重新渲染');
    return Text(MyData.of(context)!.data.toString());
  }
}
相关推荐
cdcdhj8 分钟前
利用服务工作线程serviceWorker缓存静态文件css,html,js,图片等的方法,以及更新和删除及版本控制
javascript·css·缓存·html
咔咔库奇12 分钟前
【CSS问题】margin塌陷
前端·javascript·css
764331 小时前
JavaScript ES6 继承 class
前端·javascript
谈谈叭1 小时前
Vue3中一级导航栏的吸顶导航交互以及Pinia优化重复请求
javascript·vue.js·es6·交互
好开心331 小时前
javaScript交互补充2(动画函数封装)
开发语言·前端·javascript·html·ecmascript
GISer_Jing1 小时前
Javascript_设计模式(二)
javascript·设计模式·ecmascript
️ 邪神2 小时前
【Android、IOS、Flutter、鸿蒙、ReactNative 】水平布局
flutter·ios·鸿蒙·reactnative·anroid
前端熊猫2 小时前
React 项目与 Vue 项目的区别
javascript·vue.js·react.js
linzhisong2 小时前
LayUI组件国际化多国语言版本脚本-上篇提取中文字符
前端·javascript·python·layui