Flutter - 如何将用户数据传递到所有视图

2024-05-22

我是 Flutter 世界和移动应用程序开发的新手,并且正在努力解决如何在整个应用程序中传递用户数据的问题。

我已经尝试了几件事,但似乎没有一个很好,我确信我应该遵循一些最佳实践模式。

因为它使示例更容易,所以我使用 firebase 进行身份验证。 我目前有一个单独的登录路径。登录后,我希望大多数视图中都有用户模型,用于检查显示内容的权限、在抽屉中显示用户信息等...

Firebase 有一个await firebaseAuth.currentUser();在您可能需要用户的任何地方调用它是最佳实践吗?如果是这样,拨打此电话的最佳地点在哪里?

The 颤振代码实验室 https://codelabs.developers.google.com/codelabs/flutter-firebase/显示了在允许写入之前对用户进行身份验证的一个很好的示例。但是,如果页面需要检查身份验证以确定要构建的内容,则异步调用不能进入build method.

初始化状态

我尝试过的一种方法是重写 initState 并启动调用以获取用户。当未来完成时我打电话setState并更新用户。

    FirebaseUser user;

    @override
    void initState() {
      super.initState();
      _getUserDetail();
    }

  Future<Null> _getUserDetail() async {
    User currentUser = await firebaseAuth.currentUser();
    setState(() => user = currentUser);
  }

这工作得不错,但对于每个需要它的小部件来说似乎有很多仪式。当屏幕在没有用户的情况下加载时也会出现闪烁,然后在未来完成时随用户更新。

通过构造函数传递用户

这也有效,但需要大量样板文件来让用户通过可能需要访问它们的所有路由、视图和状态。另外,我们不能只做popAndPushNamed当转换路由时,因为我们无法向其传递变量。我们必须改变类似这样的路线:

Navigator.push(context, new MaterialPageRoute(
    builder: (BuildContext context) => new MyPage(user),
));

继承的小部件

https://medium.com/@mehmetf_71205/inheriting-widgets-b7ac56dbbeb1 https://medium.com/@mehmetf_71205/inheriting-widgets-b7ac56dbbeb1

这篇文章展示了一个很好的使用模式InheritedWidget。当我将继承的小部件放置在 MaterialApp 级别时,当身份验证状态更改时,子级不会更新(我确信我做错了)

  FirebaseUser user;

  Future<Null> didChangeDependency() async {
    super.didChangeDependencies();
    User currentUser = await firebaseAuth.currentUser();
    setState(() => user = currentUser);
  }

  @override
  Widget build(BuildContext context) {
    return new UserContext(
      user,
      child: new MaterialApp(
        title: 'TC Stream',
        theme: new ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: new LoginView(title: 'TC Stream Login', analytics: analytics),
        routes: routes,
      ),
    );
  }

未来建造者

FutureBuilder 似乎也是一个不错的选择,但似乎每条路线都需要做很多工作。在下面的部分示例中,_authenticateUser()完成后获取用户和设置状态。

  @override
  Widget build(BuildContext context) {
    return new FutureBuilder<FirebaseUser>(
      future: _authenticateUser(),
      builder: (BuildContext context, AsyncSnapshot<FirebaseUser> snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return _buildProgressIndicator();
        }
        if (snapshot.connectionState == ConnectionState.done) {
          return _buildPage();
        }
      },
    );
  }

如果您提供有关最佳实践模式的建议或用于示例的资源链接,我将不胜感激。


我建议进一步调查继承的小部件;下面的代码展示了如何使用它们来异步更新数据:

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() {
  runApp(new MaterialApp(
      title: 'Inherited Widgets Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new Scaffold(
          appBar: new AppBar(
            title: new Text('Inherited Widget Example'),
          ),
          body: new NamePage())));
}

// Inherited widget for managing a name
class NameInheritedWidget extends InheritedWidget {
  const NameInheritedWidget({
    Key key,
    this.name,
    Widget child}) : super(key: key, child: child);

  final String name;

  @override
  bool updateShouldNotify(NameInheritedWidget old) {
    print('In updateShouldNotify');
    return name != old.name;
  }

  static NameInheritedWidget of(BuildContext context) {
    // You could also just directly return the name here
    // as there's only one field
    return context.inheritFromWidgetOfExactType(NameInheritedWidget);
  }
}

// Stateful widget for managing name data
class NamePage extends StatefulWidget {
  @override
  _NamePageState createState() => new _NamePageState();
}

// State for managing fetching name data over HTTP
class _NamePageState extends State<NamePage> {
  String name = 'Placeholder';

  // Fetch a name asynchonously over HTTP
  _get() async {
    var res = await http.get('https://jsonplaceholder.typicode.com/users');
    var name = json.decode(res.body)[0]['name'];
    setState(() => this.name = name); 
  }

  @override
  void initState() {
    super.initState();
    _get();
  }

  @override
  Widget build(BuildContext context) {
    return new NameInheritedWidget(
      name: name,
      child: const IntermediateWidget()
    );
  }
}

// Intermediate widget to show how inherited widgets
// can propagate changes down the widget tree
class IntermediateWidget extends StatelessWidget {
  // Using a const constructor makes the widget cacheable
  const IntermediateWidget();

  @override
  Widget build(BuildContext context) {
    return new Center(
      child: new Padding(
        padding: new EdgeInsets.all(10.0),
        child: const NameWidget()));
  }
}

class NameWidget extends StatelessWidget {
  const NameWidget();

  @override
  Widget build(BuildContext context) {
    final inheritedWidget = NameInheritedWidget.of(context);
    return new Text(
      inheritedWidget.name,
      style: Theme.of(context).textTheme.display1,
    );
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Flutter - 如何将用户数据传递到所有视图 的相关文章

  • MappedListIterable 不是子类型

    我是 flutter 和 dart 的新手 并尝试从 firestore 作为流获取数据并将其提供给我的 ListView 但我不断收到此错误 type MappedListIterable
  • 在 firebase 函数 onFinalize 中获取用于 firebase 存储的 uid

    我使用 firebase JS sdk 将音频文件上传到 firebase storage 发生这种情况时 我需要根据进行上传的经过身份验证的用户来处理它 我将其上传到其他地方进行处理 这意味着我需要在通过存储规则验证 uid 后才能访问该
  • dart,异或两个哈希码总是会返回一个新的唯一哈希码吗?

    我正在编写一个类 需要有一个基于其两个字段的唯一哈希码 我想知道对两个字段哈希码进行异或是否足以为我的对象生成唯一且一致的哈希码 class TypeMatch final Type potentialSubtype final Type
  • 如何在不需要打开应用程序的情况下显示对话框

    我正在寻找包或以任何方式显示弹出窗口 对话框或模式 而无需打开我的应用程序 例如 本地通知 但我不想使用本地通知进行自定义 flutter 中有类似的东西吗 在 Android 上 您可以使用使用 SYSTEM ALERT WINDOW 的
  • 如何解决 Firebase AuthUi 中无法找到显式活动?

    使用 firebase UI 时 我无法找到显式活动类 com firebase ui auth KickoffActivity protected void onCreate Bundle savedInstanceState super
  • 如何为发布而不是调试创建密钥库?扑

    我按照使用此网站部署 flutter 的步骤进行操作https flutter io android release https flutter io android release 当我运行 flutter build apk 时出现此错
  • Android Studio Flutter 项目错误:内存不足

    我在 Android Studio 上运行任何 flutter 项目 都会抛出内存不足错误 控制台中显示的消息如下所示 e b build slave windows engine build src third party dart ru
  • Flutter - 名称为 [DEFAULT] 的 FirebaseApp 不存在

    我正在使用 firebase 身份验证系统和 Firestore 开发一个 flutter 应用程序 我工作了3个月 之前没有遇到过这个错误 现在我在 Play 商店上发布了我的应用程序 并且我发现使用模拟器的调试版本也出现此错误 我认为已
  • Flutter 使用 RichText 填空

    我几乎完成了我的应用程序的填空实现 但不幸的是我不断遇到布局问题 然而 当我不断解决问题时 我几乎已经完成了 这是到目前为止的代码 RichText text TextSpan text dummy style TextStyle colo
  • Flutter Web 平台检查

    我正在尝试找到一种方法来查看我的 flutter web 项目正在哪个平台 iOS 或 Android 上运行 当我使用if Platform isIOS do something 我面临以下错误 Error Unsupported ope
  • 未安装 Visual Studio;这对于 Windows 开发是必要的

    My 颤振医生 https docs flutter dev get started install windows run flutter doctor是说 Visual Studio develop for Windows X Visu
  • 检查 Future 是否完成

    在 m3 之前 您可以使用 completer future isComplete 检查未来是否已完成 但这似乎已经消失了 有替代品吗 或者我需要自己保存它 似乎在 CompleterImpl 内部仍然有一个字段 isComplete 但它
  • 使用不包含 Bloc 的上下文调用 BlocProvider.of() - 即使它包含

    首先 我确实知道 BLoC 是如何运作的 它背后的想法 我知道两者之间的区别BlocProvider and BlocProvider value 构造函数 为简单起见 我的应用程序有 3 个页面 其中有一个小部件树 如下所示 App gt
  • 谷歌字体包是否会下载设备上的字体?

    在我的 flutter Android 应用程序中 第一次启动时 该应用程序显示默认字体 一秒钟后它更改为我从 google fonts flutter 包中使用的字体 我想我的问题是 应用程序第一次启动时是否会立即下载字体 如果是 可以使
  • 扑。是否可以更改 TextFormField errorText 填充?

    我在用着TextFormField with OutlineInputBorder 我需要里面的文本在右侧和左侧有填充 为此 我正在使用 contentPadding const EdgeInsets symmetric vertical
  • 使用电子邮件、用户名和密码进行 Firebase 身份验证

    我想知道是否可以使用电子邮件和用户 ID 密码登录 我有一个项目 我希望用户添加一个唯一的号码 实际上是我们公司提供的工作识别号码 以便能够签名参与该计划的人员将继续留在公司就业 即使电子邮件和密码正确但用户 ID 错误 我也需要 fire
  • 从后台恢复后,Flutter GoogleMap 为空白

    我遇到以下问题 我的 Flutter 应用程序使用 GoogleMap 地图最初加载得很好 但是 如果我将应用程序置于后台并稍后恢复 地图将保持空白 Google 徽标仍然显示 就像未指定 API 密钥时发生的情况一样 我的多边形叠加层也不
  • 使用 EditableText 进行 Flutter

    我正在尝试弄清楚如何在 Flutter 中使用 TextEditor 我有 卡片编辑器 基本上我希望能够处理相当于一段文本的内容 new EditableText autofocus true maxLines null backgroun
  • 12501 错误:Ionic 构建应用程序时使用什么密钥库

    我在用Ionic 2 with GooglePlus 身份验证 https ionicframework com docs v2 native google plus 一切都很完美iOS For Android我按如下方式构建我的应用程序
  • Flutter - 选择 TextFormField 时键盘不显示

    我目前遇到一个问题 当我选择任何一个时 键盘不会出现TextFormFielda 内的小部件Form小部件 这是表单的代码 位于我的内部CreateAccountForm有状态的小部件 import package flutter mate

随机推荐

  • Vue.js - 以编程方式设置槽内容

    有什么办法可以从组件内部设置 覆盖插槽的内容吗 喜欢 模板 div div
  • jQuery.ajax() 记录 HTTP 请求

    我有一个发送 HTTP POST 请求的函数 我想记录它以进行调试 这是函数 function serverRequest URL DATA callback ajax url URL type POST dataType text con
  • 按正确的顺序在字符串数组中查找常见字符

    我花了几天时间研究一个函数 以正确的顺序获取字符串数组中的常见字符 以创建通配符 这是一个解释我的问题的例子 我做了大约3个函数 但是当每个字母的绝对位置不同时 我总是遇到一个错误 我们假设 是 通配符 Array 0 gt 48ca135
  • _mm_max_ss 在 clang 和 gcc 之间有不同的行为

    我正在尝试使用 clang 和 gcc 交叉编译一个项目 但在使用时发现一些奇怪的差异 mm max ss e g m128 a mm set ss std numeric limits
  • 同源政策目的可疑

    正如我所读到的 同源策略是防止源自 邪恶 域 A 的脚本向 良好 域 B 发出请求 换句话说 跨站点请求伪造 玩了一下我了解到的Access Control Allow Origin标头和CORS据我了解 它允许从好域 B 指定服务器 域
  • Angular HTML 绑定

    我正在编写一个 Angular 应用程序 并且有一个想要显示的 HTML 响应 我怎么做 如果我只是使用绑定语法 myVal 它对所有 HTML 字符进行编码 当然 我需要以某种方式绑定innerHTML of a div到变量值 正确的语
  • 错误“无法将‘动态’类型的值分配给‘字符串’类型的变量。”在 Dart 2.2 中

    自上次 dart 更新 2 2 我收到这个错误 dynamic 类型的值不能分配给 dynamic 类型的变量 细绳 这对我来说没有多大意义 代码非常简单 class EmployeeMirror EmployeeMirror this i
  • 告诉 JAXB 使用注释将 解组为 Date 类

    将 JAXB 与 Java First 一起使用时 类型的字段 属性java util Date编组和解编为xs dateTime一切都按预期进行 但是如果字段 属性的类型是Object JAXB 解组xs dateTimeto XMLGr
  • 尝试模拟静态时出现 NoClassDefFoundError 或 NoSuchMethodError (不兼容的依赖项)

    When a class with static method is mocked an exception been thrown The version 2 0 0 of PowerMock displays NoClassDefFou
  • 当格式字符串包含“{”时,String.Format 异常

    我正在使用 VSTS 2008 C Net 2 0 执行以下语句时 String Format 语句抛出 FormatException 有什么想法是错误的吗 这是获取我正在使用的 template html 的位置 我想在 templat
  • 在生产者-消费者情况下使用条件变量

    我正在尝试了解条件变量以及如何在生产者 消费者情况下使用它 我有一个队列 其中一个线程将数字推入队列 而另一个线程从队列中弹出数字 当生产线程放置一些数据时 我想使用条件变量向消费线程发出信号 问题是有时 或大多数时候 它只将最多两个项目推
  • 56 CONNECT 后收到来自代理的 HTTP 代码 403?

    使用 cUrl 从我的网页生成销售人员线索时 出现 56 在 CONNECT 后从代理接收到 HTTP 代码 403 错误 该网站的 SSL 证书已过期 UPDATED 我的代码如下 curl setopt curl CURLOPT URL
  • 使用 XSLT 合并 2 个具有匹配“id”属性的 XML 文件

    当存在匹配的 id 属性时 我想使用 XSLT 合并 2 个 XML 文件 myFile1 xml 这是第一个输入文件
  • Java基于参数的同步(名为互斥锁/锁)

    我正在寻找一种根据接收到的参数来同步方法的方法 如下所示 public synchronized void doSomething name some code 我想要方法doSomething同步基于name参数如下 线程 1 doSom
  • Ruby 2 升级破坏了 Nokogiri 和/或 open-uri 编码?

    将 Rails3 2 Ruby 1 9 应用程序升级到 Rails3 2 Ruby 2 1 2 时 我有一个谜团需要解决 Nokogiri 似乎崩溃了 因为它使用 open uri 改变了它的行为 没有改变 gem 版本 只是改变 ruby
  • 使用 FileTable 通过 SQL INSERT 创建子目录

    之前 我请求如何在一个目录中创建一个目录FileTable不使用文件 I O API https stackoverflow com q 10483906 175679 我现在想为刚刚创建的父目录创建一个子目录 在插入期间如何分配我的父母
  • 布隆过滤器的使用

    我正在努力理解布隆过滤器的用处 我了解了它的底层逻辑 空间压缩 快速查找 误报等 我只是不能将这个概念应用到现实生活中 因为它是有益的 一种常见的应用是在 Web 缓存中使用布隆过滤器 我们使用布隆过滤器来确定给定的 URL 是否在缓存中
  • 部署到 Glassfish 4.1 时 URL 模式无效

    如果用户已经通过身份验证 我有一个网络过滤器可以从登录和索引页面重定向 最初我有一个无效的 URL 模式 我修复了无效模式并尝试重新部署以接收以下内容 java lang IllegalArgumentException Invalid U
  • 内核makefile中的$(call cmd,tags)这里的cmd指的是什么?

    在内核 Makefile 中我发现如下代码 ctags CTAGS CSCOPE HEADERS SOURCES ETAGS ETAGSFALGS HEADERS SOURCES call cmd ctags 另外 在哪里可以找到宏或函数
  • Flutter - 如何将用户数据传递到所有视图

    我是 Flutter 世界和移动应用程序开发的新手 并且正在努力解决如何在整个应用程序中传递用户数据的问题 我已经尝试了几件事 但似乎没有一个很好 我确信我应该遵循一些最佳实践模式 因为它使示例更容易 所以我使用 firebase 进行身份