flutter中InheritedWidget共享数据

发布时间 2024-01-10 18:13:41作者: 鲤斌

InheritedWidget是Flutter框架中用于在Widget树中共享数据的机制。它是一个特殊的Widget,可以将其放置在Widget树的上层,并向下传递共享的数据给其子Widget。子Widget可以通过InheritedWidget来获取共享的数据,而不需要通过显式地将数据传递给它们。

import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.blue, // 添加背景颜色
          title: const Text("这是导航栏2"),
        ),
        body: MyApp());
  }
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  // 定义数据
  int counter = 0;

  // 定义方法,用于改变数据
  void incrementCounter() {
    setState(() {
      counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MyInheritedWidget(
      // 将数据和方法传递给 InheritedWidget
      counter: counter,
      incrementCounter: incrementCounter,
      child: const MaterialApp(
        home: Scaffold(
          body: Column(
            children: [
              Expanded(flex: 1, child: MyAPP1()),
              Expanded(flex: 1, child: MyApp2()),
            ],
          ),
        ),
      ),
    );
  }
}

class MyInheritedWidget extends InheritedWidget {
  // 定义数据和方法
  final int counter;
  final VoidCallback incrementCounter;

  MyInheritedWidget({
    Key? key,
    required Widget child,
    required this.counter,
    required this.incrementCounter,
  }) : super(key: key, child: child);

  @override
  bool updateShouldNotify(MyInheritedWidget oldWidget) {
    // 如果数据发生变化,则通知子孙节点更新
    return counter != oldWidget.counter;
  }

  // 手动获取 InheritedWidget 的实例对象
  static MyInheritedWidget? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<MyInheritedWidget>();
  }
}

class MyAPP1 extends StatelessWidget {
  const MyAPP1({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // 使用 of 方法获取 InheritedWidget 的实例对象
    final counter = MyInheritedWidget.of(context)?.counter ?? 0;

    return Center(
      child: Container(
        color: Colors.red,
        height: double.infinity,
        width: double.infinity,
        child: Text(
          "red,当前值为:$counter", // 显示数据
          style: const TextStyle(color: Colors.white, fontSize: 24),
        ),
      ),
    );
  }
}

class MyApp2 extends StatelessWidget {
  const MyApp2({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // 使用 of 方法获取 InheritedWidget 的实例对象和方法
    final counter = MyInheritedWidget.of(context)?.counter ?? 0;
    final incrementCounter =
        MyInheritedWidget.of(context)?.incrementCounter ?? () {};

    return Center(
      child: Container(
        color: Colors.yellow,
        height: double.infinity,
        width: double.infinity,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              "yellow,当前值为:$counter", // 显示数据
              style: const TextStyle(fontSize: 24),
            ),
            ElevatedButton(
              onPressed: incrementCounter, // 调用方法
              child: const Text("按钮改变值"),
            ),
          ],
        ),
      ),
    );
  }
}