Flutter 数据共享 Provider、InheritedWidget

InheritedWidget

创建继承自 InheritedWidget 的类

class ShareWidget extends InheritedWidget {
  final int counter;

  ShareWidget({required this.counter, required Widget child}): super(child: child);

  static ShareWidget? of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType();
  }

  @override
  bool updateShouldNotify(covariant ShareWidget oldWidget) {
    return oldWidget.counter != counter;
  }
}

需要共享的widget

      body: ShareWidget(
        counter: _counter,
        child: Column(
          children: [
            ShowData(),
          ],
        ),
      ),
class ShowData extends StatefulWidget {
  @override
  State createState() => _ShowDataState();
}

class _ShowDataState extends State {
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    
    print("计数改变了");
  }

  @override
  Widget build(BuildContext context) {
    final int? num = ShareWidget.of(context)?.counter;

    return Card(
      color: Colors.blue,
      child: Text("当前计数 $num"),
    );
  }
}

Provider

导入 provider 库

  1. 创建需要共享的数据
class CounterViewModel extends ChangeNotifier {
  int _counter = 100;

  int get counter => _counter;

  set counter(int value) {
    _counter = value;
    notifyListeners();
  }
}
  1. 在应用程序的顶层创建 ChangeNotifierProvider
void main() {
  runApp(ChangeNotifierProvider(
      create: (context) => CounterViewModel(), child: MyApp()));
}

多个 viewmodel

void main() {
  runApp(MultiProvider(providers: providers, child: MyApp()));
}

List providers = [
  ChangeNotifierProvider(create: (context) => CounterViewModel()),
  ChangeNotifierProvider(create: (context) => UserViewModel())
];
  1. 使用共享的数据

区别:

  • Provider.of: 当 Provider 中的数据发生改变时,Provider 所在的 widget 整个 build 方法都会重新构建
  • Consumer:当 Provider 中的数据发生改变时,只会重新执行 Consumer 中的 builderbuilder 中的 child 参数防止重复构建 widget。
  • Selector:
    -- selector 方法,对原有的数据进行转换。
    -- shouldRebuild 方法,是否需要重新构建。
class ShowData extends StatefulWidget {
  @override
  State createState() => _ShowDataState();
}

class _ShowDataState extends State {
  @override
  Widget build(BuildContext context) {
    return Card(
      color: Colors.blue,
      child: Consumer(builder: (context, viewmodel, child) {
        return Text("当前计数 ${viewmodel.counter}");
      }),
    );
  }

/* 或者使用 Provider
  @override
  Widget build(BuildContext context) {
    // 3.使用共享的数据
    int counter = Provider.of(context).counter;

    return Card(
      color: Colors.blue,
      child: Text("当前计数 $counter"),
    );
  }
  */
}

Selector2Selector3Selector4Selector5Selector6

Consumer2Consumer3Consumer4Consumer5Consumer6

      child: Consumer2(
          builder: (context, counterVM, userVM, child) {
        return Text("当前计数 ${counterVM.counter}");
      }),
  1. 赋值
Consumer
        floatingActionButton: Consumer(
          builder: (context, viewmodel, child) {
            return FloatingActionButton(
              child: child,
              onPressed: () {
                viewmodel.counter++;
              },
            );
          },
          child: Icon(Icons.add),
        )
Selector
        floatingActionButton: Selector(
          selector: (context, viewmodel) => viewmodel,
          shouldRebuild: (pre, nex) => false, // 是否需要重新构建
          builder: (context, viewmodel, child) {
            return FloatingActionButton(
              child: child,
              onPressed: () {
                viewmodel.counter++;
              },
            );
          },
          child: Icon(Icons.add),
        )

你可能感兴趣的:(Flutter 数据共享 Provider、InheritedWidget)