flutter 专题八 官方状态管理 Provider基本使用

一、简介

当App的复杂性发展到一定程度,就会出现一个页面中不同深度的子Widget需要共享访问同一个数据状态,甚至不同页面需要共享同一个状态的情况,这时我们可能会想到InheritedWidget。InheritedWidget是 Flutter 中非常重要的一个功能型组件,它提供了一种在 Widget 树中从上到下共享数据的方式,比如我们在应用的根 Widget 中通过InheritedWidget共享了一个数据,那么我们便可以在任意子Widget 中来获取该共享的数据。而Provider就是对InheritedWidget组件的上层封装,使其更易用,更易复用。具有如下一些特点:

  • 简化资源的分配/释放
  • 实现懒加载
  • 减少创建新类时的样板代码
  • 对 Flutter 开发工具友好,使你的应用状态在 Flutter 开发工具中可见
  • 提供一种常见的方式来消费这些 InheritedWidgets

二、在正式介绍Provider之前,让我们先来看几个Provider涉及的几个概念:

  • Provider:一个提供数据源并促进应用程序内数据访问的包。 我们可以使用 ChangeNotifier 类来创建数据, 此类可变状态,并在其中的数据发生更改时通知侦听器。
  • Consumer:用于访问数据提供者的值并跟踪其更改, 它驻留在数据提供者的小部件树中,并根据相关数据重建自身。 换句话说,作为数据的消费者,当数据发生变化时,它会自动更新。
  • Provider.of():此方法允许开发者访问小部件树中最近的数据提供者,它使开发者能够检索相关数据并跟踪更新。
  • ChangeNotifier:此类构成数据提供者的基础,通过创建一个扩展 ChangeNotifier 类的类,开发者可以可变状态。 当数据发生变化时,可以通过调用notifyListeners()方法通知监听者。

下面我们就来讲讲Flutter官方推荐的Provider状态管理框架如何使用。为了方便讲解和说明,我们使用官方的计数器例子。

三、首先,我们在Flutter项目的pubspec.yaml 文件中添加如下依赖:

dependencies:
  flutter:
    sdk: flutter
  provider: ^6.0.5

四、按照Provider的使用流程,我们首先需要创建一个Provider数据提供者,该类主要用来管理数据源。

import 'package:flutter/foundation.dart';


class CounterProvider with ChangeNotifier {
  int _count = 0;
  int get count => _count;
  void increment() {
    _count++;
    notifyListeners();
  }
}

五、接下来,在Flutter小部件树的顶层创建一个 MultiProvider ,并将创建的数据提供程序添加到其中,如下所示

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';


void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => CounterProvider()),
      ],
      child: MyApp(),
    ),
  );
}

六、最后,在需要接收这些数据的地方使用 Consumer 小部件就可以获得Provider中的数据。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Text(
                'Count: ${context.watch().count}',
                style: Theme.of(context).textTheme.headline4,
              ),
            ],
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () =>
              context.read().increment(),
          tooltip: 'Increment',
          child: const Icon(Icons.add),
        ),
      ),
    );
  }
}

在上面的示例中,我们访问 CounterProvider 类中的计数变量,就会在有更新时自动重建小部件。通过使用Provider全局状态管理,开发者可以轻松地在Flutter应用程序中实现数据共享。完整的代码如下:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';


// Step 1: Create a data provider class
class CounterProvider with ChangeNotifier {
  int _count = 0;
  int get count => _count;
  void increment() {
    _count++;
    notifyListeners();
  }
}
void main() {
  runApp(
    // Step 2: Wrap your app with MultiProvider
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => CounterProvider()),
      ],
      child: MyApp(),
    ),
  );
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Provider Example',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: HomePage(),
    );
  }
}
class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Step 3: Use the Consumer widget to access data
    return Consumer(
      builder: (context, counterProvider, child) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Counter App'),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(
                  'Count:',
                  style: TextStyle(fontSize: 24),
                ),
                Text(
                  '${counterProvider.count}',
                  style: TextStyle(fontSize: 48, fontWeight: FontWeight.bold),
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              // Step 4: Trigger state update
              counterProvider.increment();
            },
            child: Icon(Icons.add),
          ),
        );
      },
    );
  }
}

你可能感兴趣的:(Flutter面试与实战,flutter)