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

详细解释下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.mfbz.cn/a/767460.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

理解 REST API 和 GraphQL 的区别

你可能听说过 GraphQL&#xff0c;但对它与 REST 的区别还不完全确定。今天我们将介绍 REST 和 GraphQL 的一些基本原理&#xff0c;以及它们的不同使用场景。 GraphQL 作为 REST API 的替代品越来越受欢迎&#xff0c;不过它不一定是完全的“替代品”。 根据你的使用情景&am…

LLM笔记:训练大模型之并行化

1 数据并行 最常见的并行化手段主要是把数据分成多个块&#xff0c;然后每个节点就可以在本地独立的跑各自的数据任务&#xff0c;最后再和其他节点通信&#xff0c;进而汇总最后的结果好处就是计算效率高&#xff0c;每个节点可以独自计算自己的任务且这种方法易于实现缺点就…

【Python基础篇】一篇文章入门Python,进入Python的世界

文章目录 0.前言1.打印&#xff08;Hello&#xff0c;World&#xff09;2.创建变量3.打印升级3.1 打印一句话中间加变量3.2 sep设置分隔符3.3 end和换行 4. 注释 0.前言 大家好&#xff0c;我是小辰&#xff0c;前几天做了个重大的决定&#xff0c;学习python。 首先&#xff0…

博途S7-1500PLC“虚轴“编程应用

1、CODESYS如何添加虚轴 如何添加虚轴(AM400PLC)-CSDN博客文章浏览阅读164次。EtherCAT运动控制总线启用的时候,选择EtherCAT总线任务周期。选择好后,选择点击添加。https://rxxw-control.blog.csdn.net/article/details/139898985虚轴是利用软件算法实现的运动控制轨迹规划…

外挂级OCR神器:免费文档解析、表格识别、手写识别、古籍识别、PDF转Word

智能文档解析&#xff1a;大模型友好的文档解析工具 PDF转Markdown 支持将任意格式的文件&#xff08;图片、PDF、Doc&#xff0f;Docx、网页等&#xff09;解析为Markdown或Json格式&#xff0c;以对LLM友好的方式呈现。 更高速度&#xff1a;100页PDF最快1.5s完成解析 更大…

DEBOPIE框架:打造最好的ChatGPT交易机器人

本文介绍了如何利用 DEBOPIE 框架并基于 ChatGPT 创建高效交易机器人&#xff0c;并强调了在使用 AI 辅助交易时需要注意的限制以及操作步骤。原文: Build the Best ChatGPT Trading Bots with my “DEBOPIE” Framework 如今有大量文章介绍如何通过 ChatGPT 帮助决定如何以及在…

Hi3861 OpenHarmony嵌入式应用入门--TCP Server

本篇使用的是lwip编写tcp服务端。需要提前准备好一个PARAM_HOTSPOT_SSID宏定义的热点&#xff0c;并且密码为PARAM_HOTSPOT_PSK LwIP简介 LwIP是什么&#xff1f; A Lightweight TCP/IP stack 一个轻量级的TCP/IP协议栈 详细介绍请参考LwIP项目官网&#xff1a;lwIP - A Li…

6.7、函数的分文件编写

mian函数部分代码 #include <iostream> using namespace std; #include <string> #include "swap.h"//函数的分文件编写 //实现两个数字进行交换的函数//函数的声明 //void swap(int a,int b); //函数的定义 //void swap(int a, int b) //{ // int temp…

9. Revit API UI: UIView、UIDocument、框选聚焦

9. Revit API UI: UIView、UIDocument、框选聚焦 UI命名空间下的API&#xff0c;到这里差不多就要讲完了&#xff0c;同Application那篇所讲的几个类与接口&#xff0c;都是带UI的对应了一个不带UI的&#xff0c;如UIApplication和Application&#xff0c;作用呢&#xff0c;也…

Python基于PyQt5和卷积神经网络分类模型(CNN分类算法)实现时装类别识别系统GUI界面项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 随着深度学习技术的发展&#xff0c;计算机视觉领域取得了显著的进步&#xff0c;特别是在图像分类、目…

Java8环境安装(jdk1.8安装)详细教程

Java 8环境安装&#xff08;jdk1.8安装&#xff09;详细教程 Java 8&#xff08;也称为JDK 1.8&#xff09;&#xff0c;是Oracle公司于2014年3月发布的一个重要的Java语言版本。这个版本自发布以来&#xff0c;因其众多的新特性和改进&#xff0c;被认为是Java语言发展历程中…

渗透测试之注入

命令注入 命令注入相关分隔符&#xff1a; 字符说明;仅限Linux环境&#xff0c;用于隔开命令&#xff0c;按顺序执行|前面命令的输出结果作为后面命令的输入内容||前提是前面的命令执行失败&#xff0c;和&&号相反&前后两条命令依次执行&&前提是前面的命…

虚拟机的网络配置

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️ 每一步都向着梦想靠近&#xff0c;坚持就是胜利的序曲 一 …

优化服务,推动企业向前发展

在快速变化的商业环境中&#xff0c;企业的成长离不开优质的服务支持。成都树莓集团&#xff0c;作为数字产业生态链的重要构建者&#xff0c;始终将优化服务、助力企业成长作为自身的核心使命。通过全方位、一站式的服务模式&#xff0c;树莓集团为企业提供强大的支持&#xf…

Idea-Idea配置gitIgnore忽略文件

背景 在项目提交到Git过程中&#xff0c;总有一些文件&#xff0c;例如.idea和.iml等这些我们不想提交的&#xff0c;直接添加进入gitIgnore文件中自动忽略掉。 Idea安装插件 1、在File->Setting->Plugins中搜索gitIgnore并安装插件 2、项目右键new->.ignore File-…

vue实现一个简单的审批绘制功能

1、vue代码 <div class"approval"><div class"approval_ul" v-for"(item,key) in approvalList" :key"key"><div><el-radio-group v-model"item.jointlySign"><el-radio label"1">…

P3374 【模板】树状数组 1

题目描述 如题&#xff0c;已知一个数列&#xff0c;你需要进行下面两种操作&#xff1a; 将某一个数加上 &#x1d465;x 求出某区间每一个数的和 输入格式 第一行包含两个正整数 &#x1d45b;,&#x1d45a;n,m&#xff0c;分别表示该数列数字的个数和操作的总个数。 …

秋招突击——7/2——复习{}——新作{分割等和子集、不同路径、最小路径和、最长回文子串}

文章目录 引言复习新作分割等和子集个人实现参考实现 不同路径个人实现参考实现 最小路径和个人实现参考实现 最长回文子串个人实现参考实现字符串哈希二分 总结 引言 今天起的挺早的&#xff0c;早上把昨天录得关于JVM的相关八股都听完了&#xff0c;然后还背了一部分八股&am…

用Chromatix进行tuning流程

##一、基本调试 ###1、工程初始配置&#xff1a; 这个工具就是一个图形化的参数编辑器&#xff0c;其实所有tuning中的效果参数直接改文件参数酒醒&#xff0c;工具的好处是&#xff1a;带有检查错误和模拟的功能以及一些校验工具和脚本。 初始化可以中需要的配置&#xff1a;t…

基于Java的音乐网站系统01239

目 录 摘要 1 绪论 1.1 研究背景 1.2系统开发目标、意义 1.3研究内容 2 相关技术介绍 2.1 MySQL数据库 2.2 Java编程语言 2.3 SpringBoot框架介绍 3 系统需求分析与设计 3.1 可行性分析 3.1.1 技术可行性分析 3.1.2 经济可行性分析 3.1.3 法律可行性分析 3.2 需…