Flutter笔记--provider

136 阅读2分钟

Flutter中的Provider是一个流行的状态管理库,它基于InheritedWidget构建,允许在整个应用程序中共享状态并监听其变化。Provider是一个轻量级、易于使用的库,旨在帮助开发人员有效地管理应用程序中的状态。通过使用Provider,开发者可以避免手动传递数据模型,使得状态管理变得更加简单和高效。

工作原理:Provider的工作原理基于Flutter的InheritedWidget机制。它通过创建一个InheritedWidget,将数据模型传递给整个应用程序的组件树。当数据模型发生变化时,Provider会自动通知依赖它的组件,并触发重新构建。

使用方法:在Flutter应用的顶层使用ChangeNotifierProvider来包裹整个应用或特定部分,可以在任何子Widget中使用Provider.of(context)或Consumer来访问和响应状态的变化。

注意事项:需要注意的是,Provider的作用域是有限的,当在Provider的子树之外的Widget中调用Provider.of(context)时,它将会抛出一个异常。因此,在使用Provider时,需要将它放在需要共享数据的Widget的父节点上,以确保Provider的作用域覆盖所有需要使用共享数据的Widget。

demo: 添加依赖:provider: ^6.1.2

import 'dart:async';
import 'dart:convert';
import 'dart:math';

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/physics.dart';
import 'package:simple_animations/simple_animations.dart';
import 'package:supercharged/supercharged.dart';
import 'package:flutter/foundation.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => Counter()),
      ],
      child: const MyApp111(),
    ),
  );
}
class Counter with ChangeNotifier, DiagnosticableTreeMixin {
  int _count = 0;
  int get count => _count;
  void increment() {
    _count++;
    notifyListeners();
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(IntProperty('count', count));
  }
}

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: MyHomePage123(),
    );
  }
}

class MyHomePage123 extends StatelessWidget {
  const MyHomePage123({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Provider Example'),
      ),
      body: const Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('You have pushed the button this many times:'),
            Count(),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        key: const Key('increment_floatingActionButton'),
        onPressed: () => context.read<Counter>().increment(),
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

class Count extends StatelessWidget {
  const Count({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Text(
      '${context.watch<Counter>().count}',
      key: const Key('counterState'),
      style: Theme.of(context).textTheme.headlineMedium,
    );
  }
}