flutter组件 InheritedWidget

发布于:2024-04-29 ⋅ 阅读:(196) ⋅ 点赞:(0)

InheritedWidget是 一个数据共享组件,它提供了一种在 widget 树中从上到下共享数据的方式,比如我们在应用的根 widget 中通过InheritedWidget共享了一个数据,那么我们便可以在任意子widget 中来获取该共享的数据!

官方说明:Base class for widgets that efficiently propagate information down the tree.
翻译:有效地沿树向下传播信息的 widgets  的基类。
作者释义:在 widget 树中从上到下共享数据的方式,类似于react的context。

使用方法:

需要继承 InheritedWidget 类,并且实现 updateShouldNotify 方法。

当共享数据发生变化时会调用 updateShouldNotify,返回一个bool类型数据。判断是否通知子树中依赖共享数据的Widget重新buildupdateShouldNotify会触发子组件的 didChangeDependencies生命周期。

示例:

import 'package:flutter/material.dart';

main(List<String> args)=> runApp(const MyApp());

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  int count = 0;

  
  Widget build(BuildContext context) {
    return CounterInheritedWidget(
      count: count,
      addCount: addCount,
      child: const MaterialApp(
        home: Scaffold(
          body: CounterWidget(),
        ),
      ),
    );
  }

  addCount(){
    setState(() {
      count++;
    });
  }
}

// 创建一个继承自 InheritedWidget 的类,用于传递计数器值
class CounterInheritedWidget extends InheritedWidget{
  const CounterInheritedWidget({
    super.key,
    required this.count,
    required this.addCount,
    required super.child
  });
  final int count; // 计数值
  final Function addCount; // 用于修改计数值的方法

  // 该回调决定当count发生变化时,是否通知子树中依赖count的Widget重新build
  
  bool updateShouldNotify(CounterInheritedWidget oldWidget) {
    return oldWidget.count != count;
  }

  // 定义一个便捷方法,方便子树中的widget获取共享数据
  static CounterInheritedWidget? of(BuildContext context){
    return context.dependOnInheritedWidgetOfExactType<CounterInheritedWidget>();
  }
}

class CounterWidget extends StatelessWidget {
  const CounterWidget({super.key});

  
  Widget build(BuildContext context) {
    return const Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          ShowCounterWidget(),
          AddCounterWidget()
        ],
      ),
    );
  }
}

class ShowCounterWidget extends StatefulWidget {
  const ShowCounterWidget({super.key});

  
  State<ShowCounterWidget> createState() => _ShowCounterWidgetState();
}

class _ShowCounterWidgetState extends State<ShowCounterWidget> {
  
  Widget build(BuildContext context) {
    // 在这里,我们可以使用 CounterInheritedWidget.of(context)!.count 来获取计数值
    return Text(CounterInheritedWidget.of(context)!.count.toString());
  }

  
  void didChangeDependencies(){
    print('count被修改了');
    super.didChangeDependencies();
  }
}

class AddCounterWidget extends StatelessWidget {
  const AddCounterWidget({super.key});

  
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () {
        // 使用 CounterInheritedWidget.of(context)!.addCount 来自增计数值
        CounterInheritedWidget.of(context)!.addCount();
      },
      child: const Text('自增')
    );
  }
}

使用思想:
InheritedWidget实际上就是给子组件一个拥有共享数据的变量,通过当前 Widget 的context去获取共享数据。在修改共享数据时,需要宿主 Widget 提供方法去修改。

如有错误请及时与作者联系~~非常感谢