Flutter实战项目-第四篇 页面路由、provider状态管理

2023-11-03

概要

  • 页面路由配置
  • provider

一、路由配置

创建router.dart用于管理所有的路由,然后再main.dart MaterialApp中注册路由。

router.dart中第一个routeName="/",即是默认打开的页面

import './view/login/login.dart';
class JDRouter {
  static final routes = {
    Login.routeName: (context) => const Login()
  };
}

main.dart

import 'package:flutter/material.dart';
import 'router.dart';
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      routes: JDRouter.routes,
    );
  }
}

二、状态管理

        provider官方推荐的状态管理,类似Vuex和reduce之类。其可以全局注册,也可以局部注册,用户可根据自己的实际需求选择注册方式。因为状态的改变会触发build,所以用户使用是应当避免反复的build消耗。provider本身支持监听多个,但是也是有数量限制,具体可以查阅官方资料。当前只是介绍了最常用的情况。

        2.1全局注册

        创建文件global.notifier.dart

import 'package:flutter/material.dart';

class GlobalNotifier with ChangeNotifier{
  //底部导航栏按钮状态
  int menuIndex =0;
  void increment(int param){
    menuIndex = param;
    notifyListeners();
  }
}

在main.dart中注册

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'router.dart';
import 'store/global.notifier.dart';
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<GlobalNotifier>(create: (_)=>GlobalNotifier()),
      ],
      child:MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        routes: JDRouter.routes,
      )
    );
  }
}

页面中使用监听及更新值

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

import '../../store/global.notifier.dart';
class Login extends StatefulWidget {
  /// 登录页面
  const Login({Key? key}) : super(key: key);
  static const routeName = '/';
  @override
  State<Login> createState() => _LoginState();
}

class _LoginState extends State<Login> {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      padding: EdgeInsets.all(20),
      child: Consumer<GlobalNotifier>(
        builder: (_, globalNotifier,child){
          return Column(
            children:[
              Text('${globalNotifier.menuIndex}'),
              TextButton(
                onPressed: (){
                  globalNotifier.increment(10);
                },
                child: Text("更新值")
              )
            ]
          );
        }
      )
    );
  }
}

代码中获取值/设置

Provider.of<GlobalNotifier>(context).menuIndex

Provider.of<GlobalNotifier>(context).menuIndex

///需在initsate之后使用
Provider.of<GlobalNotifier>(context,listen: false).increment(10);

多个监听时

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

import '../../store/global.notifier.dart';
import '../../store/login/login.notifier.dart';
class Login extends StatefulWidget {
  /// 登录页面
  const Login({Key? key}) : super(key: key);
  static const routeName = '/';
  @override
  State<Login> createState() => _LoginState();
}

class _LoginState extends State<Login> {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      padding: EdgeInsets.all(20),
      child: Consumer2<GlobalNotifier,LoginNotifier>(
        builder: (_, globalNotifier,loginNotifier,child){
          return Column(
            children:[
              Text('${globalNotifier.menuIndex}${loginNotifier.name}'),
              TextButton(
                onPressed: (){
                  globalNotifier.increment(10);
                  loginNotifier.increment('JavonHuang');
                },
                child: Text("更新值")
              )
            ]
          );
        }
      )
    );
  }
}

2.2局部注册

        通过ChangeNotifierProvider可以使实现局部注册

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

import '../../store/global.notifier.dart';
import '../../store/login/login.notifier.dart';
class Login extends StatefulWidget {
  /// 登录页面
  const Login({Key? key}) : super(key: key);
  static const routeName = '/';
  @override
  State<Login> createState() => _LoginState();
}

class _LoginState extends State<Login> {
  @override
  Widget build(BuildContext context) {
    return  ChangeNotifierProvider<LoginNotifier>(
      create: (_) => LoginNotifier(),
      child:Container(
      color: Colors.white,
      padding: EdgeInsets.all(20),
      child: Consumer<LoginNotifier>(
        builder: (_,loginNotifier,child){
          return Column(
            children:[
              Text('${loginNotifier.name}'),
              TextButton(
                onPressed: (){
                  // globalNotifier.increment(10);
                  loginNotifier.increment('JavonHuang');
                },
                child: Text("更新值")
              )
            ]
          );
        }
      )
    ) ,
    );
  }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Flutter实战项目-第四篇 页面路由、provider状态管理 的相关文章

  • AVAudioPlayer 无法从网站播放 m4a 或 mp3 文件类型

    我试图在我的应用程序中找到一个仅纯 m4a 声音的 URL 我有音频的 URL 理论上可以下载它 然后 使用下载的文件URL到声音 我尝试使用AVAudioPlayer播放它 但它不播放任何声音 这是我的代码 在 URL 检索函数中 我调用
  • 是否有 ADB 命令来检查媒体是否正在播放

    我想使用 ADB 命令检查根植于终端的外部设备中是否正在播放音频 视频 我无法找到任何 ADB 命令 如果有 我尝试过 adb shell dumpsys media player 我想要一个命令来指定视频是否正在运行 您可以使用以下命令查
  • Android MediaExtractor seek() 对 MP3 音频文件的准确性

    我在使用 Android 时无法在eek 上获得合理的准确度MediaExtractor 对于某些文件 例如this one http www archive org download emma solo librivox emma 01
  • Flutter:构造函数中 List 参数的默认分配

    在定义构造函数时 是否可以将常量值分配给数据类型 List 的可选参数 例如 class sample final int x final List
  • 发布android后更改应用内购买项目的价格

    在 Google Play 上发布后 是否可以更改应用内购买商品的价格 我假设该应用程序也已发布 完整的在线文档位于http developer android com http developer android com也http sup
  • 你的CPU不支持NX

    我刚刚下载了 android studio 但是我遇到了一个问题 当我运行它时 它说你的 cpu 不支持 NX 我应该怎么办 NX 或实际上是 NX 处理器位 是处理器的一项功能 有助于保护您的 PC 免受恶意软件的攻击 当此功能未启用并且
  • 如何在PreferenceActivity中添加工具栏

    我已经使用首选项创建了应用程序设置 但我注意到 我的 PreferenceActivity 中没有工具栏 如何将工具栏添加到我的 PreferenceActivity 中 My code 我的 pref xml
  • 在 SQLite 中搜索时排除 HTML 标签和一些 UNICODE 字符

    更新 4 我已经成功运行了firstchar例如 但现在的问题是使用regex 即使包含头文件 它也无法识别regex操作员 有什么线索可以解决这个问题吗 更新 2 我已经编译了sqlite3我的项目中的库 我现在正在寻找任何人帮助我为我的
  • 如何在颤动中从图像选择器中裁剪图像?

    我想允许用户裁剪他从图像选择器中选择的图像并保存它 类似于在 Whatsapp 上上传个人资料图片 我怎样才能在颤振中做到这一点 示例图片 您可以使用这2个flutter库来实现这一点 图像选择器 图像裁剪器 图像选择器使用iOS和Andr
  • Android Studio 0.4.3 Eclipse项目没有gradle

    在此版本之前 在 Android Studio 中按原样打开 Eclipse 项目似乎很容易 无需任何转换 我更喜欢 Android Studio 环境 但我正在开发一个使用 eclipse 作为主要 IDE 的项目 我不想只为这个项目下载
  • 字符串数组文本格式化

    我有这个字符串 String text Address 1 Street nr 45 Address 2 Street nr 67 Address 3 Street nr 56 n Phone number 000000000 稍后将被使用
  • 诊断和仪器均缺少“僵尸”选项

    运行 Xcode 4 0 2 Zombie 选项丢失 其他 SO 帖子建议找到它的两个地方 Product gt Run looks like this Product gt Profile looks like this 奇怪的是 我之前
  • ios8 键盘高度有所不同

    我使用下面的代码来获取键盘高度 该高度在带有 ios8 的 iPhone 5s 设备中与带有 ios7 的 IPhone4s 设备中有所不同 因此 当我在带有 ios8 的 iPhone5s 中点击它时 我的文本字段移动得非常高 而相同的代
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • .isProviderEnabled(LocationManager.NETWORK_PROVIDER) 在 Android 中始终为 true

    我不知道为什么 但我的变量isNetowrkEnabled总是返回 true 我的设备上是否启用互联网并不重要 这是我的GPSTracker class public class GPSTracker extends Service imp
  • 如何确定对手机号码的呼叫是本地呼叫还是 STD 或 ISD

    我正在为 Android 开发某种应用程序 但不知道如何获取被叫号码是本地或 STD 的号码的数据 即手机号码检查器等应用程序从哪里获取数据 注意 我说的是手机号码 而不是固定电话 固定电话号码 你得到的数字是字符串类型 因此 您可以获取号
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • 将两个文本视图并排放置在布局中

    我有两个文本视图 需要在布局中并排放置 并且必须遵守两条规则 Textview2 始终需要完整显示 如果布局中没有足够的空间 则必须裁剪 Textview1 例子 文本视图1 文本视图2 Teeeeeeeeeeeeeeeeeextview1
  • android sdk 的位置尚未在 Windows 操作系统的首选项中设置

    在 Eclipse 上 我转到 windows gt Android SDK 和 AVD Manager 然后弹出此消息 Android sdk 的位置尚未在首选项中设置 进入首选项 在侧边栏找到 Android 然后会出现一个 SDK 位
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两

随机推荐

  • UITabBarItem

    UITabBarController UITabBar UIBarItem UITabBarItem UITabBarItem就是UITabBar上显示的小按钮 我们也可以定制系统UITabBarItem按钮 只需通过UITabBarIte
  • C/C++的64位整型 zz

    为了和DSP兼容 TSint64和TUint64设置成TSint40和TUint40一样的数 结果VC中还是认为是32位的 显然不合适 typedef signed long int TSint64 typedef unsigned lon
  • 初始化 Repo错误 错误信息:fatal: error [Errno 111] Connection refused

    错误信息 fatal error Errno 111 Connection refused 解决方法 修改home 目录下的 bashrc文件 gedit bashrc 在文件的末尾添加如下命令 export PATH bin PATH e
  • QT5.6静态编译添加ODBC数据库

    qt5 6已经编译好 现在添加ODBC数据库的支持 1 进入qt everywhere opensource src 5 6 3 qtbase src plugins sqldrivers odbc目录 运行qmake exe 然后再运行n
  • C语言学生管理系统课程设计

    include
  • cookie和session之间的关系

    当登录接口依赖token的 可以先登录后 token存到一个yaml或者json或者ini的配置文件里面 后面所有的请求去拿这个数据就可以全局使用 如果是cookies的参数 可以用session自动关联 详情如下 一 cookie与ses
  • 超全!深度学习在计算机视觉领域的应用一览

    计算机视觉领域正在从统计方法转向深度学习神经网络方法 计算机视觉中仍有许多具有挑战性的问题需要解决 然而 深度学习方法正在针对某些特定问题取得最新成果 在最基本的问题上 最有趣的不仅仅是深度学习模型的表现 事实上 单个模型可以从图像中学习意
  • MySQL查询数据库中所有表名及注释等信息

    1 查询所有表名 select table name from information schema tables where table schema 当前数据库 2 查看所有字段和字段注释 SELECT COLUMN NAME 字段 c
  • torch.Size理解

    torch Size括号中有几个数字就是几维 第一层 最外层 中括号里面包含了两个中括号 以逗号进行分割 这就是 2 3 4 中的2 第二层中括号里面包含了三个中括号 以逗号进行分割 这就是 2 3 4 中的3 第三层中括号里面包含了四个数
  • Python中MD5加密

    MD5是什么 下面的概念是百度百科的 Message Digest Algorithm MD5 中文名为消息摘要算法第五版 为计算机安全领域广泛使用的一种散列函数 用以提供消息的完整性保护 该算法的文件号为RFC 1321 R Rivest
  • ev3编程 python_乐高 EV3 高级编程 - 第四课:Python 模块

    译者按 使用 ev3dev Linux 系统并用 Python 编程的人数比例很低 好像这一课这样写 Python 编程的就更少了 你会发现程序的重用率会大大的提高 EV3 Lesson 4 Python Modules EV3 第 4 课
  • win10 电脑 .Net framework3.5 组件无法安装0x800f801f

    最近在win10上安装了MotorControl Workbench 5 4 0软件需要用到 Net framework3 5 但是安装Net framework3 5老是出错 无论是下载离线安装包安装 还是通过 控制面板 中 程序 的 启
  • 【SSM框架系列】Spring IoC(控制反转) & DI(依赖注入)

    Spring是什么 Spring是分层的 Java SE EE应用 full stack 轻量级开源框架 以 IoC Inverse Of Control 反转控制 和 AOP Aspect Oriented Programming 面向切
  • 指数增强(股票)——Python量化

    指数增强策略 目录 指数增强策略 1 策略原理 2 策略步骤 3 策略代码 4 回测结果和稳健性分析 1 策略原理 说到指数增强 就不得不说指数 在进行股票投资时 有一种分类方式是将投资分为主动型投资和被动型投资 被动型投资是指完全复制指数
  • python对dataframe中series的json格式解析

    方法1 如果df里只有一列json格式 可以保存为txt 然后再删掉列名 在进行处理 import pandas as pd result with open r C Users Administrator Desktop json处理 t
  • 【你不知道的JavaScript】(05)作用域+闭包+编译执行过程

    本文章仅针对我自己在看书过程中对一些不太清楚的知识点进行查漏补缺 你不知道的JavaScript 上卷 第一部分作用域和闭包 编译与执行 传统编译语言的编译过程 词法分析 语法分析 代码生成 而JavaScript语言则要更复杂 JS引擎不
  • mac 访问钥匙串中创建系统证书失败 未知错误的解决方案

    If you cannot store the certificate in the System keychain create it in the login keychain then exported it You can then
  • 慢日志分析工具mysqldumpslow

    慢查询分析工具mysqldumpslow mysqldumpslow OPTS LOGS 后跟参数以及log文件的绝对地址 s 按照那种方式排序 c 访问计数 l 锁定时间 r 返回记录 al 平均锁定时间 ar 平均访问记录数 at 平均
  • c#和js的交互(转)

    如何在 C 中访问 JavaScript 函数 答案如下 c 代码中执行 javaScript 函数 方法一 1 Page RegisterStartupScript ggg 方法二 使用 Literal 类 然后 private void
  • Flutter实战项目-第四篇 页面路由、provider状态管理

    概要 页面路由配置 provider 一 路由配置 创建router dart用于管理所有的路由 然后再main dart MaterialApp中注册路由 router dart中第一个routeName 即是默认打开的页面 import