个性化阅读
专注于IT技术分析

Flutter状态管理

在本节中, 我们将讨论状态管理以及如何在Flutter中处理状态管理。我们知道在Flutter中, 一切都是小部件。小部件可以分为两类, 一类是无状态小部件, 另一类是有状态小部件。无状态窗口小部件没有任何内部状态。这意味着一旦构建完成, 我们将无法对其进行更改或修改, 除非它们再次被初始化。另一方面, 有状态窗口小部件是动态的并且具有状态。这意味着我们可以在其整个生命周期中轻松修改它, 而无需再次对其进行初始化。

什么是状态?

状态是在构建窗口小部件时可以读取的信息, 并且可能会在应用程序的整个生命周期内进行更改或修改。如果要更改窗口小部件, 则需要更新状态对象, 这可以通过使用有状态窗口小部件可用的setState()函数来完成。 setState()函数使我们可以设置触发UI重绘的状态对象的属性。

状态管理是应用程序生命周期中最流行且必要的过程之一。根据官方文档, Flutter是声明性的。这意味着Flutter通过反映应用程序的当前状态来构建其UI。下图更清楚地说明了你可以在哪里从应用程序状态构建UI。

Flutter状态管理

让我们以一个简单的例子来了解状态管理的概念。假设你已在应用程序中创建了客户或产品列表。现在, 假设你已在该列表中动态添加了新客户或产品。然后, 需要刷新列表以查看新添加到记录中的项目。因此, 无论何时添加新项目, 都需要刷新列表。这种类型的编程需要状态管理来处理这种情况以提高性能。这是因为每次你进行更改或更新时, 状态都会刷新。

在Flutter中, 状态管理分为两种概念类型, 如下所示:

  1. 暂时状态
  2. 应用状态

暂时状态

此状态也称为UI状态或本地状态。它是与特定窗口小部件相关的一种状态, 或者可以说它是包含在单个窗口小部件中的状态。在这种状态下, 你无需使用状态管理技术。此状态的常见示例是“文本字段”。

class MyHomepage extends StatefulWidget {
  @override
  MyHomepageState createState() => MyHomepageState();
}

class MyHomepageState extends State<MyHomepage> {
  String _name = "Peter";

  @override
  Widget build(BuildContext context) {
    return RaisedButton(
        child: Text(_name), onPressed: () {
           setState(() {
              _name = _name == "Peter" ? "John" : "Peter";
           });
         }, );
  }
}

在上面的示例中, _name是短暂状态。在这里, 只有StatefulWidget类中的setState()函数可以访问_name。生成方法调用setState()函数, 该函数对状态变量进行修改。执行此方法时, 小部件对象将替换为新的小部件对象, 从而提供修改后的变量值。

应用状态

它与短暂状态不同。这是一种状态, 我们希望在应用程序的各个部分之间共享, 并且希望保持用户会话之间的状态。因此, 这种类型的状态可以全局使用。有时也称为应用程序状态或共享状态。此状态的一些示例是用户首选项, 登录信息, 社交网络应用程序中的通知, 电子商务应用程序中的购物车, 新闻应用程序中文章的已读/未读状态等。

下图更恰当地说明了短暂状态和应用程序状态之间的区别。

Flutter状态管理

可通过使用提供程序包来学习应用程序状态管理的最简单示例。提供者的状态管理很容易理解, 并且需要更少的编码。提供者是第三方库。在这里, 我们需要了解使用此库的三个主要概念。

  1. 变更通知者
  2. ChangeNotifierProvider
  3. 消费者

变更通知者

ChangeNotifier是一个简单的类, 它向其侦听器提供更改通知。对于少数听众来说, 它很容易理解, 实现和优化。它用于侦听器观察变化的模型。在此, 我们仅使用notifyListener()方法来通知侦听器。

例如, 让我们基于ChangeNotifier定义一个模型。在此模型中, 使用ChangeNotifier扩展了Counter, 该计数器用于在我们调用notifyListeners()时通知其侦听器。它是唯一需要在ChangeNotifier模型中实现的方法。在此示例中, 我们声明了两个函数递增和递减, 这两个函数用于增加和减小值。每当模型更改时, 我们都可以以可能更改应用程序UI的方式调用notifyListeners()方法。

import 'package:flutter/material.dart';

class Counter with ChangeNotifier {
  int _counter;

  Counter(this._counter);

  getCounter() => _counter;
  setCounter(int counter) => _counter = counter;

  void increment() {
    _counter++;
    notifyListeners();
  }

  void decrement() {
    _counter--;
    notifyListeners();
  }
}

ChangeNotifierProvider

ChangeNotifierProvider是向其后代提供ChangeNotifier实例的窗口小部件。它来自提供程序包。以下代码段有助于理解ChangeNotifierProvider的概念。

在这里, 我们定义了一个构建器, 该构建器将创建Counter模型的新实例。除非有必要, 否则ChangeNotifierProvider不会重建Counter。当不再需要该实例时, 它还将自动在Counter模型上调用dispose()方法。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.indigo, ), home: ChangeNotifierProvider<CounterModel>(
        builder: (_) => CounterModel(), child: CounterView(), ), );
  }
}

如果需要提供多个类, 则可以使用MultiProvider。 MultiProvider是在其范围内使用的所有不同Provider的列表。如果不使用它, 我们将必须嵌套我们的提供者, 而其中一个是另一个的孩子。我们可以从下面的代码中了解这一点。

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(builder: (context) => Counter()), Provider(builder: (context) => SomeOtherClass()), ], child: MyApp(), ), );
}

消费者

这是一种提供者, 不做任何花哨的工作。它只是在新的小部件中调用提供程序, 并将其构建实现委派给构建器。以下代码对其进行了更清晰的说明。

return Consumer<Counter>(
  builder: (context, count, child) {
    return Text("Total price: ${count.total}");
  }, );

在上面的示例中, 你可以看到使用者窗口小部件仅需要一个构建器函数, 只要ChangeNotifier发生更改, 就会调用该函数。 builder函数包含三个参数, 分别是上下文, 计数和子代。第一个参数, 上下文, 包含在每个build()方法中。第二个参数是ChangeNotifier的实例, 第三个参数是用于优化的子级。最好将使用者小部件放在树中尽可能深的位置。


赞(0)
未经允许不得转载:srcmini » Flutter状态管理

评论 抢沙发

评论前必须登录!