[译] Flutter 中的原生应用程序状态

_InheritedProvider({this.data, this.child})
super(child: child);

final data;
final child;

@override
bool updateShouldNotify(_InheritedProvider oldWidget) {
return data != oldWidget.data;
}
}

“InheritedWidget” 的所有子类都应该实现 “updateShouldNotify” 方法。此时,我们只需检查传递的 “data” 是否已更改。例如,当我们将计数器从 “0” 改为 “1” 时,该方法应该返回 “true”。

我们现在讲“继承”小部件,然后添加到小部件树中:

class Provider extends StatelessWidget {

@override
Widget build(BuildContext context) {
return new _InheritedProvider(data: data, child: child);
}

}

好的,我们现在有了小部件,它在小部件树中传播数据,但我们应该创建一个公有方法,它允许 get 这个数据:

class Provider extends StatelessWidget {

static of(BuildContext context) {
_InheritedProvider p =
context.inheritFromWidgetOfExactType(_InheritedProvider);
return p.data;
}

}

inheritFromWidgetOfExactType” 方法获取 “_InheritedProvider” 类型实例的最近父部件。

我们现在有了解决第一个问题的能力:

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Provider(
data: 0,

}

}

class MyHomePage extends StatelessWidget {

Widget build(BuildContext context) {
var _counter = Provider.of(context);

}

我们删除了全局变量 “_counter” 并使用 “Provider.of” 在 “MyHomePage” 小部件中取得了 “counter”。如你所见,我们没有将它作为参数传递给 “MyHomePage”,而是使用 “Provider.of” 来获取应用程序的状态,他可以应用于树下的任何小部件。 此外,“Provider.of” 还包括当前小部件的上下文和重建,并在更改 “_InheritedProvider” 小部件时对其进行注册

现在是时候检测我们的应用程序是否起作用了:我们重新加载它。为了确保我们的 “Provider” 正常工作,我们可以将 “data” 从 “0” 更改为 “MyApp” 小部件中的 “1”,然后我们必须重新加载应用程序。然而,我们的 “+” 按钮仍然无法工作。

在这里,我们面临的第二个问题是“如何在改变应用程序的状态后重建小部件”,现在我们应该重新开始思考。

我们的应用程序状态只是一个数字,但当这个数字被更改时,检测起来就没有那么容易了。如果我们将“计数器”编号包装成一个“可观察的”对象,该对象将跟踪更改并通知“监听器”这些更改。

庆幸的是,Flutter 已经有了解决方案,这就是 “ValueNotifier”。像通常一样,这里有一个很好的文档解释:

value 被替代时,这个类会通知它的监听器。

好的,让我们在 “mian.dart” 中创建应用程序的状态类:

import ‘package:flutter/material.dart’;
import ‘package:myapp/Provider.dart’;

class AppState extends ValueNotifier {
AppState(value) : super(value);
}

var appState = new AppState(0);

然后将其传递给 “Provider”

Widget build(BuildContext context) {
return new Provider(
data: appState,

由于 “data” 包含一个对象,所以我们更改 “Provider.of(context)” 用法,那就这样做:

Widget build(BuildContext context) {
var _counter = Provider.of(context).value;

重建我们的应用程序,并确保没有错误。

我们现在已经实现了 “_incrementCounter”:

floatingActionButton: new FloatingActionButton(
onPressed: () => _incrementCounter(context),
tooltip: ‘Increment’,
child: new Icon(Icons.add),
),
);
}

_incrementCounter(context) {
var appState = Provider.of(context);
appState.value += 1;
}

我们重新加载了应用程序,并尝试按下 “+” 按钮。没有改变什么。但如果我们允许“热加载”,我们将看到文本已经改变。这是因为我们按下按钮后改变了应用程序的状态。但我们在屏幕上看到了旧的状态,因为我们还没有重新构建小部件。当我们允许小部件进行“热加载”时,我们就可以看到屏幕上的实际状态。

最后的挑战是在我们更改应用程序的状态后重建小部件。但在此之前,我们看看已有的东西:

  1. “Provider” —— 我们应用程序状态的容器
  2. “AppState” —— 跟踪应用程序状态改变并通知“监听者”的类
  3. “_InheritedProvider” —— 小部件将有效地将应用程序状态传播到网上,并在改变了自己的状态之后重建用户。

首先,我们回顾一下 “_InheritedProvider” 的 “updateShouldNotify” 方法:

@override
bool updateShouldNotify(_InheritedProvider oldWidget) {
return data != oldWidget.data;
}

现在 “data” 等于 “AppState” 的实例,这意味着我们在 “_incrementCounter” 方法中更改此实例的 “value” 时,它实际上并不会改变实例本身。因此,这个比较总是返回 “false”。我们通过比较 “value”-s 来解决这个问题。但为此,我们应该将“值”曝出在小部件中,这允许我们可以不丢失重构之间的 “value”:

class _InheritedProvider extends InheritedWidget {
_InheritedProvider({this.data, this.child})
: _dataValue = data.value,
super(child: child);

final data;
final child;
final _dataValue;

@override
bool updateShouldNotify(_InheritedProvider oldWidget) {
return _dataValue != oldWidget._dataValue;
}
}

现在它可以正确地工作了:当我们改变状态值时,小部件会重新构建消费者。但在重新构建消费者之前,我们应该在改变应用程序的状态后重建小部件本身。

我们的代码中只有一个可以了解 “_InheritedProvider” 的小部件,就是 “Provider” 小部件。如果我们想要跟踪小部件中的某种状态,我们应该创建 “statefull” 小部件。好的,让我们将 “Provider” 小部件从 “stateless” 转换为 “statefull”:

class Provider extends StatefulWidget {
const Provider({this.child, this.data});

static of(BuildContext context) {
_InheritedProvider p =
context.inheritFromWidgetOfExactType(_InheritedProvider);
return p.data;
}

final ValueNotifier data;
final Widget child;

@override
State createState() => new _ProviderState();
}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

尾声

一转眼时间真的过的飞快。我们各奔东西,也各自踏上了自己的旅途,但是即使多年不见,也因为这份情谊我们依旧如从前那般“亲密”。不忘初心方得始终。加油吧,程序员们,在我看来35岁,40岁从来不是危机,只要永远不要忘记自己为何踏上征程!

最后需要同款资料的,可以 **私信我点击【学习】**我愿意分享给你!

为了让更多在学习中或者最近要准备面试的朋友们看到这篇文章,希望你们能多多评论,点赞+转发!

因为这份情谊我们依旧如从前那般“亲密”。不忘初心方得始终。加油吧,程序员们,在我看来35岁,40岁从来不是危机,只要永远不要忘记自己为何踏上征程!

最后需要同款资料的,可以 **私信我点击【学习】**我愿意分享给你!

为了让更多在学习中或者最近要准备面试的朋友们看到这篇文章,希望你们能多多评论,点赞+转发!

再次感谢所有给我提供过题目的朋友们,感谢一路有你!

  • 24
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值