flutter - Flutter:当变量更改而不在每个页面上调用它时,如何使其在整个应用程序中显示“请验证”页面?
问题描述
所以我的想法是,我创建了一个“请验证”页面,其中除了指纹和显示“触摸验证”的文本外没有其他任何显示,然后应用程序会显示设备指纹/面部 ID 验证。
我想在每次布尔变量更改时都显示此页面,而无需在每个页面上明确告知它。
我有一个具有needToAuthenticate
布尔变量的类,如果它是真的,我想显示“触摸身份验证”页面。因此,如果我在 10 分钟后将此变量设置为 true,则会显示此页面,并且在验证之前不会让用户去其他任何地方。
如果我的应用中有 2 个页面,我不希望这样:
第 1 页:
...
_needToAuthenticate = CustomAuthentication.getNeedToAuthenticate();
@override
build() {
return _needToAuthenticate ? showAuthenticationPage() : showTheActualThingThisPageNeedToHave();
}
...
第2页:
...
_needToAuthenticate = CustomAuthentication.getNeedToAuthenticate();
@override
build() {
return _needToAuthenticate ? showAuthenticationPage() : showTheActualThingThisPageNeedToHave();
}
...
如您所见,代码重复。不喜欢。我想如果更改侦听器正在检查中的布尔变量CustomAuthentication
,如果将其设置为 true,它将显示“请验证”页面。第 1 页和第 2 页应如下所示:
第 1 页:
...
@override
build() {
return showTheActualThingThisPageNeedToHave();
}
...
第2页:
...
@override
build() {
return showTheActualThingThisPageNeedToHave();
}
...
但如果变量设置为 true,则在这些页面前面将显示“请验证”页面。
目前我使用一个while (needToAuthenticate) authenticate();
代码,但这会无限循环,直到用户进行身份验证。
提前致谢。
解决方案
您可以将inheritedWidget与streamingSharedPreferences -plugin 一起使用。
创建一个小部件来保存“设置”:
class AppSettings extends InheritedWidget {
// Preferences
static String _needToAuthenticateKey = 'MY_KEY';
@override
bool updateShouldNotify(InheritedWidget oldWidget) => true;
static AppSettings of(BuildContext context) =>
context.dependOnInheritedWidgetOfExactType<AppSettings>();
AppSettings({Widget child, StreamingSharedPreferences preferences})
: _needToAuthenticate = preferences.getBool(_needToAuthenticateKey , defaultValue: true),
super(child: child);
final Preference<bool> _needToAuthenticate;
Stream<bool> streamNeedToAuthenticate() => _needToAuthenticate;
void setNeedToAuthenticate(bool value) => _needToAuthenticate.setValue(value);
}
并包装您的应用程序的入口点:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:streaming_shared_preferences/streaming_shared_preferences.dart';
// TODO Do not forget to import the AppSettings here
void main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
final StreamingSharedPreferences _preferences;
const MyApp({StreamingSharedPreferences preferences})
: this._preferences = preferences;
@override
Widget build(BuildContext context) {
return AppSettings(
preferences: this._preferences,
child: Builder(
builder: (context) {
AppSettings.of(context).streamNeedToAuthenticate()
.listen((event) {(/*Ask for identification*/)})
return MaterialApp(
title: applicationName,
home: /*Your application*/,
);
}),
);
}
}
免责声明:我没有针对您的用例对此进行测试,但我以类似的方式使用该插件。
推荐阅读
- c - 有没有办法将未知类型的数组作为参数传递给 C 中的函数?
- android - React Native:使用 `pop()` 或 `goBack()` 时的性能问题,导致无限循环。但是使用`reset`很好
- regex - 删除除模式和下一行 vim 之外的所有内容
- python-3.x - 为 Open AI GymTaxi 环境保存视频/GIF 文件
- laravel - 新的 Laravel 构建 - 发布请求超时
- sql - 如何修复'System.IndexOutOfRangeException:'位置 0 处没有行。' 错误?
- c# - Xamarin.Android 如何使“wav”文件成为应用程序的默认推送通知声音?
- python - 如何通过 selenium 和 python 从下拉菜单中选择元素?
- scala - 丢弃身份验证器时,如何解决与剪影 scala 库的不一致问题?
- amazon-web-services - 在ecs aws中运行terraform destroy时,它会先删除一个服务,然后需要很长时间才能删除任务