详细解释下flutter初始示例的代码

news2024/10/7 20:31:24

详细解释下flutter初始示例的代码

main

Image1

首句导入需要的包 类似于其他语言的import

main函数为入口函数 包裹MyApp类

MyApp

Image2

这个类继承自无状态类 可见myapp不管理任何状态

build方法是所有widget内必须实现的方法

此处返回一个 ChangeNotferiProvider 可以看到它用于管理应用状态 并在状态改变时通知管理器

child 部分使用一个便捷的widget(部件)

此处使用MaterialApp 开发Material Design 应用的widget

MaterialApp需要一些参数来定义应用外观与结构\

title: 应用标题 通常显示在任务区管理器中

theme: 应用主题 这里用ThemeData 并设置useMaterial3 为ture启用material design 3 的特性 同时使用ColorScheme.fromSeed 生成颜色方案 这边使用绿色

home 定义首页widget 这里使用自定义的 MyHomePage widget

MyHomePage

下一步让我们导航到 MyHomePage作为主页 它包含了应用的主要部分

Image3

此处可以看到继承了Stateful,此处表示MyHomepage可以维护改变自己的状态.

So,什么是StatefulWidget?

StatefulWidget

是指widget在其生命周期内可能改变的数据.当你想要构建一个用户界面这个界面随着用户交付或者其他因素(如网络请求)而变化时 则使用StatefulWidget

MyHomePage

Image4

让我们视角回到HomePage

  • createState()方法是StatefulWidget类中必须实现的方法,它的作用是创建一个State对象。这个State对象包含了widget的状态,并且当widget的状态改变时,Flutter框架会调用这个State对象的build方法来重新构建UI。
  • _MyHomePageState类是MyHomePage的状态类,它继承自State<MyHomePage>。这个类包含了MyHomePage widget的状态和逻辑代码。当你需要更新UI时,你会在这个类中改变状态,并调用setState()方法,这会触发UI的重建。

总的来说,StatefulWidget和它的状态类(如_MyHomePageState)一起工作,允许Flutter应用响应状态的变化并更新UI。

_MyHomePage

让我们来看下全部代码中最复杂的部分

分成两部分来看

第一部分

Image5

此处定义一个状态码 selectedIndex = 0 用来切换 两个 页面 一个首页 一个 收藏页

第二部分

Image6

每个 build 方法都必须返回一个 widget 或(更常见的)嵌套 widget 树。

在本例中,顶层 widget 是 Scaffold。它是一个有用的 widget。在绝大多数真实的 Flutter 应用中都可以找到该 widget。

让我们逐句往下看

  1. return Scaffold(...);: 返回一个 Scaffold(脚手架) widget,它提供了一个框架,用于实现基本的 material design 布局结构,如顶部栏、底部栏、抽屉菜单等。

  2. body: Row(...);: Scaffoldbody 属性设置为一个 Row widget,这意味着它的子元素将水平排列。

    Scaffoldbody属性可以接受任何Widget作为其子项。这意味着除了Row之外,你还可以使用许多其他类型的Widget。以下是一些可用作Scaffoldbody属性的Widget类型的例子:

    1. Column:与Row相似,但是它是垂直排列子项的。
    2. Container:一个常用于装饰、定位和大小调整的Widget
    3. Stack:用于重叠多个子项的Widget
    4. ListView:用于展示一个滚动列表。
    5. GridView:用于展示一个二维列表,类似于网格。
    6. SingleChildScrollView:当有一个单个子项需要滚动时使用。
    7. Center:可以将其子项居中显示。
    8. Padding:用于给其子项添加填充。
    9. Expanded:用于在RowColumnFlex中扩展子项以填充可用空间。

    这些只是一些例子,Flutter提供了大量的Widget,几乎可以在Scaffoldbody中使用任何Widget来创建所需的布局。

  3. SafeArea(...);: SafeArea widget 确保其子 widget 不会被操作系统的状态栏、导航栏等遮挡。

  4. NavigationRail(...);: NavigationRail 是一个用于导航的 widget,它显示在屏幕的一侧,提供了几个目的地(destinations)供用户选择。这在宽屏或平板设备上特别有用。

    • extended: constraints.maxWidth > 600,: 根据屏幕宽度自动切换 NavigationRail 的展开状态。如果屏幕宽度大于 600 像素,则展开显示。

    • destinations: [...]: 定义了两个导航目的地,每个目的地都有一个图标和标签。

    • Image7

    • selectedIndex: selectedIndex,: 指定当前选中的导航项。具体来说这里如果是0 那么第一个导航栏会一直显示被选中的颜色

    • onDestinationSelected: (value) {...}: 当用户选择一个不同的导航项时,这个回调函数会被触发,更新选中项的状态。

    • Image8

  5. Expanded(...);: Expanded widget 使其子 widget 能够填充 Row 中剩余的空间。

    这里的Expanded 表示 组建 如何 扩展 填充 额外的空间

  6. Container(...);: 这个 Container 作为页面的主要内容区域,其背景色设置为当前主题的 primaryContainer 颜色。

  7. child: page,: Container 的子 widget 设置为 page,这里 page 可能是一个动态的 widget,根据 selectedIndex 的值显示不同的内容。

总的来说,这段代码创建了一个具有侧边导航栏的布局,用户可以通过点击 NavigationRail 中的项来切换显示在主内容区域的页面。这种布局适合于宽屏设备或平板电脑,可以提供清晰的导航体验。

GeneratorPage

作为第一个页面

Image9

简单看下这个界面 , 按照flutter的思维方式,

这段代码定义了一个名为GeneratorPageStatelessWidget,它是Flutter中用于构建UI的一个基本组件。GeneratorPage组件的作用是展示一个中心对齐的页面,页面上有一个大卡片(BigCard)和两个按钮(“Like"和"Next”)。下面是对代码的详细解释:

  1. 类定义:

    • class GeneratorPage extends StatelessWidget:定义了一个名为GeneratorPage的类,它继承自StatelessWidgetStatelessWidget是一个不保存状态的widget,它的内容是固定的,当输入数据改变时,Flutter框架会创建一个新的StatelessWidget实例。
  2. build方法:

    • Widget build(BuildContext context):这是所有Widget类必须实现的方法,它返回一个Widget对象,这个对象描述了如何根据当前的状态和配置信息构建UI。
  3. 获取状态和数据:

    • var appState = context.watch<MyAppState>();:使用context.watch<T>()方法获取MyAppState的实例。这是Flutter的状态管理机制之一,允许Widget监听某个状态对象的变化,并在状态变化时重建UI。
    • var pair = appState.current;:从appState中获取当前的数据项(pair)。
  4. 决定图标:

    • 根据appState.favorites.contains(pair)的结果,决定icon变量应该是Icons.favorite(已收藏)还是Icons.favorite_border(未收藏)。这是通过检查当前项pair是否在收藏列表favorites中来决定的。
  5. 构建UI:

    • Scaffold:一个提供了基本的Material Design布局结构的widget,例如顶部栏、底部导航栏、抽屉等。
    • Center:一个使其子widget居中显示的widget。
    • Column:一个在垂直方向上排列子widget的widget。
    • BigCard(pair: pair):一个自定义的widget,显示当前的数据项pair。这里假设BigCard是一个用于展示pair信息的大卡片。
    • SizedBox(height: 10):一个具有固定高度的盒子,用于在两个按钮之间添加垂直间距。
    • Row:一个在水平方向上排列子widget的widget。
    • ElevatedButton.iconElevatedButton:分别表示带图标的按钮和普通按钮。这两个按钮分别绑定了点击事件,点击时分别调用appState.toggleFavorite()appState.getNext()方法,用于切换当前项的收藏状态和获取下一个数据项。

总的来说,这段代码通过GeneratorPage组件展示了一个包含大卡片和两个操作按钮的页面,用户可以通过点击按钮来浏览和收藏数据项。

So 这里的appstate是什么意思呢?

要解释这个问题要看到上文的MyappState

Image10

这个Myappstate继承自一个具有 修改后提示能力的基类 也就是 说

Myappstate 可以 在自己的状态修改后告知 监听 Myappstate的类

视角回到GP

Image11

查看下build:

这里的appState 继承自 监听MyAppState

然后使用 IconData icon; 声明一个flutter 的 icon变量 这里如果 被收藏了 那么这里 就使用 实心 新型图标 如果没有就用 空心 图标

让整个项目更结构化

还可另外在最外层启一个assests来存放静态资源

  1. 创建文件夹结构

    • lib/: 存放所有Dart代码。
      • models/: 存放模型类。
      • views/: 存放UI界面。
        • pages/: 存放页面文件。
        • widgets/: 存放自定义小部件。
      • providers/: 存放状态管理相关的类。
      • utils/: 存放工具类或帮助函数。
      • themes/: 存放主题相关的代码。
  2. 拆分代码到不同文件

    • models/word_pair_model.dart: 可以存放WordPair相关的模型代码。
    • providers/my_app_state.dart: 存放MyAppState类。
    • views/pages/my_home_page.dart: 存放MyHomePage类。
    • views/pages/favorites_page.dart: 存放FavoritesPage类。
    • views/pages/generator_page.dart: 存放GeneratorPage类。
    • views/widgets/big_card.dart: 存放BigCard小部件。
    • themes/app_theme.dart: 存放主题相关的代码。
  3. 修改main.dart

    • main.dart应该只包含main()函数和MyApp类。其他的类应该移动到相应的文件中。
  4. 更新导入

    • 在拆分代码后,确保更新每个文件中的导入语句,以正确引用其他文件。

首先拆分 MyappState内的定义 从main.dart移动到 my_app_state.dart

拆分完成后可以看到 项目结构 清晰了 不少

Image12

稍微加点什么

让我们有个想法 让我们 整出来 第三个 页面 它的作用是请求 www.baidu.com 并把请求内容打印出来 到页面上

  1. 让我们在api里面新建一个baidu.dart

    Image13

  2. 解下来让我们新建一个页面 称为 news_page.dart 调用Api获取信息

  3. Image14

  4. now 让我们在 my_home_page中注册它吧

    Image15

    1. 然后在我们点击按钮后,you got it !

    2. Image16

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1889342.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年低碳发展与地球科学国际会议 (LCDES 2024)

2024年低碳发展与地球科学国际会议 (LCDES 2024) 2024 International Conference on Low Carbon Development and Earth Science 【重要信息】 大会地点&#xff1a;长沙 大会官网&#xff1a;http://www.iclcdes.com 投稿邮箱&#xff1a;iclcdessub-conf.com 【注意&#xf…

一个opencv实现检测程序

引言 图像处理是计算机视觉中的一个重要领域&#xff0c;它在许多应用中扮演着关键角色&#xff0c;如自动驾驶、医疗图像分析和人脸识别等。边缘检测是图像处理中的基本任务之一&#xff0c;它用于识别图像中的显著边界。本文将通过一个基于 Python 和 OpenCV 的示例程序&…

《昇思25天学习打卡营第6天|网络构建》

文章目录 前言&#xff1a;今日所学&#xff1a;1. 定义模型类2. 模型层3. 模型参数 前言&#xff1a; 在第六节中我们学习了网络构建&#xff0c;了解了神经网络模型是由神经网络层和Tensor操作构成&#xff0c;我们使用的mindspore.nn中提供了常见的升级网络层的实现&#x…

c++边界处理机制

1.vector std::vector&#xff1a;std::vector 是动态数组&#xff0c;它会在运行时动态地调整存储空间大小&#xff0c;因此当访问超出边界时&#xff0c;会触发运行时异常 std::out_of_range。可以通过try-catch块来捕获这种异常来处理越界访问。 #include <iostream>…

十五、【源码】给代理对象设置属性

源码地址&#xff1a;https://github.com/spring-projects/spring-framework 仓库地址&#xff1a;https://gitcode.net/qq_42665745/spring/-/tree/15-proxy-set-property 给代理对象设置属性 之前的代码是创建Bean进行判断&#xff0c;要不要进行代理&#xff0c;如果代理…

console 报错 之 Uncaught (in promise) RangeError: Maximum call stack size exceeded

1. 背景 demo 环境报错。。。 2. 报错问题 3. 问题原因 vue 报错: “RangeError: Maximum call stack size exceeded” 报错通常是由于无限的递归 导致的。当使用 Vue 路由时&#xff0c;如果设置不当&#xff0c;会导致无限的递归&#xff0c;最终导致栈溢出&#xff0c;即…

【TypeScript】TS入门到实战(详解:高级类型)

目录 第三章、TypeScript的数据类型 3.1 TypeScript的高级类型 3.1.1 class 3.1.1.1 熟悉class类 3.1.1.2 class类继承的两种方式 3.1.1.3 class类的5种修饰符 3.1.2 类型兼容 3.1.3 交叉类型 3.1.4 泛型 3.1.4.1 创建泛型函数 3.1.4.2 泛型函数的调用 3.1.4.3 泛型…

【操作与配置】Linux的CPU深度学习环境

Conda安装 可浏览官网&#xff1a;Miniconda — Anaconda 文档 这四条命令会快速而且悄悄地安装最新的64位安装程序&#xff0c;然后清理安装过程中产生的文件。如果需要安装 Linux 版本的其他版本或架构的 Miniconda&#xff0c;只需要在命令中更改安装程序的名称。 mkdir …

【C++】const详解

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文作为 JohnKi &#xff0c;引用了部分大佬的案例 &#x1f4e2;未来很长&#xff0c;…

【Kali-linux for WSL】图形化界面安装

文章目录 前言图形化界面安装 前言 之前在WSL中安装了Kali 启动之后发现什么都没有&#xff01;&#xff01;&#xff01; 那我还怎么学习渗透技术&#xff1f;&#xff1f;&#xff1f; 看来&#xff0c;得改进下我的kali-linux for wsl&#xff0c;安装个图形化界面 图形化…

JCR一区级 | Matlab实现BO-Transformer-LSTM多变量回归预测

JCR一区级 | Matlab实现BO-Transformer-LSTM多变量回归预测 目录 JCR一区级 | Matlab实现BO-Transformer-LSTM多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现BO-Transformer-LSTM多变量回归预测&#xff0c;贝叶斯优化Transformer结合LSTM长…

【Python】Python中的常量与变量

常量与变量 导读一、新建项目二、常量2.1 字面常量2.2 特殊常量 三、变量3.1 变量的定义3.2 变量的命名3.2.1 关键字 结语 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 在上一篇内容中我们详细介绍了Python环境的搭建过程&#xff0c;…

一键转换,高效管理:引领文件批量改后缀名与TXT转DOCX格式新潮流

在这个数字化时代&#xff0c;文件管理和格式转换成为了我们日常工作中不可或缺的一部分。然而&#xff0c;手动更改文件后缀名以及将TXT文件转换为DOCX格式&#xff0c;不仅耗时耗力&#xff0c;还容易出错。幸运的是&#xff0c;我们有了文件批量改名高手这款强大的工具&…

【JAVA多线程】JDK中的各种锁,看这一篇就够了

目录 1.概论 1.1.实现锁的要素 1.2.阻塞队列 1.3.Lock接口和Sync类 2.各种锁 2.1.互斥锁 2.1.1.概论 2.1.2.源码 1.lock() 2.unlock() 2.2.读写锁 2.3.Condition 2.3.1.概论 2.3.2.底层实现 1.概论 1.1.实现锁的要素 JAVA中的锁都是可重入的锁&#xff0c;因为…

固定网国内数据传送业务经营许可证

一、国内固定网数据传送业务是什么&#xff1f; 固定网国内数据传送业务是指互联网数据传送业务以外的&#xff0c;在固定网中以有线方式提供的国内端到端数据传送业务。主要包括基于IP承载网、ATM网、X.25分组交换网、DDN网、帧中继网络的数据传送业务等。该业务属于A2类基础…

数字源表表征及测试纳米材料高温原位方案

01/纳米材料电学性能的表征和分析/ 与传统的材料相比&#xff0c;纳米材料具有原子级厚度、表面平整无悬空键、载流子迁移率好等优点&#xff0c;其导电性能很大程度依赖于材料本身的带隙、掺杂浓度和载流子迁移率。同样的掺杂浓度下&#xff0c;迁移率越大&#xff0c;电阻率…

计算机网络--网络层

一、网络层的服务和功能 网络层主要为应用层提供端对端的数据传输服务 网络层接受运输层的报文段&#xff0c;添加自己的首部&#xff0c;形成网络层分组。分组是网络层的传输单元。网络层分组在各个站点的网络层之间传输&#xff0c;最终到达接收方的网络层。接收方网络层将运…

nginx SSI(Server Side Include)服务端包含 合并拼装静态内容

一、什么是SSI 在被传送给浏览器之前&#xff0c;服务器会对 HTML 文档进行完全地读取、分析以及修改&#xff0c;使用SSI指令将文本、图片或代码信息包含到网页中。对于整个页面可以拆分成多个模块&#xff0c;通过SSI指令将几个模块拼接成一个完整的页面&#xff0c;当有内容…

大模型在软件测试领域的应用场景有哪些?_大模型在测试领域应用

在数字化转型的大背景下&#xff0c;在软件定义一切的趋势下&#xff0c;软件测试人员需要接触和理解的信息越来越多&#xff0c;并呈现加速增长的态势。需求越来越大&#xff0c;交付周期越来越短&#xff0c;受制于体力和能力限制&#xff0c;测试人员的效率和质量难以同步提…

基于模式识别的垃圾分类系统-计算机毕业设计源码96151

摘 要 随着城市化进程的加速和人口的不断增长&#xff0c;垃圾管理和环境保护成为了全球面临的重要挑战之一。垃圾分类作为一种可行的解决方案&#xff0c;旨在减少垃圾的数量、降低环境污染&#xff0c;并促进资源的回收与再利用。 本文旨在设计并开发一个垃圾分类系统。该系统…