当前位置: 首页 > news >正文

Flutter完整开发指南 | FlutterDart – The Complete Guide

文章目录

    • 一、分析一个新的flutter项目
    • 二、程序设计语言的工作原理
    • 三、从头开始理解函数
    • 四、如何启动flutter应用程序
    • 五、理解小部件
    • 六、使用第一个小部件并将值传递给函数
    • 七、位置参数和命名参数
    • 八、组合多个小部件
    • 九、理解const值
    • 十、构建更复杂的部件树
    • 十一、了解值类型
    • 十二、配置小部件和了解对象
    • 十三、使用配置对象(非部件对象)
    • 十四、泛型,列表和添加渐变颜色
    • 十五、如何配置小部件和对象
    • 十六、练习文本样式
    • 十七、自定义小部件,为什么需要它们
    • 十八、理解类
    • 十九、构建自定义小部件
    • 二十、使用构造函数
    • 二十一、跨文件拆分代码
    • 二十二、练习创建自定义小部件
    • 二十三、引入变量
    • 二十四、变量和类型-结合两个关键概念
    • 二十五、final & const -特殊类型的变量
    • 二十六、实例变量(属性)和可配置的小部件
    • 二十七、练习可重用的部件和构造函数
    • 二十八、显示图像和使用多个构造函数

一、分析一个新的flutter项目

在硬盘上的任何位置创建一个新的flutter项目

dart文件在lib文件夹中,lib是存放dart和flutter代码的文件夹:

image-20250310193946669

各个平台的文件夹仅包含平台特定的文件,通常情况下不用更改,flutter在需要时自动更改和配置这些文件。

image-20250310194514970

build文件夹只包含flutter为不同目标平台构建应用时生成的临时文件和输出文件

image-20250310195016920

test文件夹可以编写测试主应用程序代码的代码,可以定义自动化测试,对于早期捕获错误以及确保不必手动测试所有内容非常有用。

以.开始的文件夹,保存了一些额外的配置

.gitignore是git使用的文件,版本控制软件,可以用来管理代码快照。

.metadate由flutter自动管理,用于跟踪有关项目的一些内部信息和元数据。

analysis_options.yaml配置了一些flutter和dart工具,代码编辑器使用这些工具在运行应用程序之前显示代码中的警告和错误。默认设置足够了,也可以根据喜好调整这些设置,例如:强制执行某种编写代码的风格,如果不小心使用了另外一种风格或类似的东西会警告。

pubspec.yaml可以编辑,可以添加第三方软件包到flutter项目。你想为你的应用程序添加一些功能,而不想自己构建,因为太麻烦或者复杂,但它也没有内置在flutter或dart中,就可以引入一个第三方软件包。

README.md文件中包含了一些关于这个项目的一般信息,简短的描述和一些资源,可以访问这些资源深入了解flutter

在这里插入图片描述

二、程序设计语言的工作原理

像dart这样的代码不会被andriod或iOS设备理解,在编译之前,dart最终会从上到下遍历这个代码文件,并从上到下读取代码文件,解析这个代码文件。

void main() {runApp(const MyApp());
}

代码和代码文件由dart解析,构建项目以便在目标平台上运行。

代码被解析之后,他必须被翻译成目标平台可以理解的语言,刚刚提到的,这些代码不能在andriod或iOS或其他目标平台上执行。

下一步,在解析代码之后,代码被各种dart和flutter工具编译,意味着他被转换成一些其他代码,一些原生ios或andriod机器代码,因此,这些代码可以被ios或andriod或任何目标平台所理解。

因此,使用dart和flutter编写的代码将被转换成其他代码,然后这些代码最终被打包,捆绑在一起成为一个高度优化的代码包,然后,该代码包再将项目交付到的设备上执行。

以上就是dart代码的情况。这些目标设备上执行的是编译后的代码。

三、从头开始理解函数

image-20250310204051601

import 'package:flutter/material.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({super.key});

可以看到一堆单词,一堆单词行,不是真正的句子,只是单词的组合,这就是编程的全部。

组合不同的单词来创建语句、指令,然后告诉计算机或移动终端最终要做什么,在屏幕上显示什么,点击按钮时要做什么等等。

创建这些指令有两个主要类别的单词

第一类是关键字(keywords),这些词内置在一种语言中,在该语言中执行或触发非常特定的事情。

例如,import是内置在Dart中的关键字,最终将一个文件连接到另一个文件。

另一类词是标识符,作为一个开发人员自己定义的词。例如以下代码中的MyApp,也可以用其他替换,例如MeineApp

class MyApp extends StatelessWidget {const MyApp({super.key});

像visual studio code这样的代码编辑器可以检测不同类型的单词,有一个语法突出的显示的内置功能,使代码更具有可读性,为不同的单词分配不同的颜色。例如extends/class和import都是蓝色都是关键字。不同的颜色被用于不同种类的单词。

runApp();

这就是函数,函数是可以在代码中执行的简单指令,runApp是一个函数,一个由flutter框架提供的指令,这个指令是关于启动和运行应用程序的,它的主要工作实际上是在屏幕上显示一些用户界面。

image-20250311193825269

有条红色的曲线,表示代码有问题。鼠标悬停在错误上,会看到问题的详细描述。

必须提供函数体

image-20250311194020326

创建一个自定义函数,一个自定义指令。

void 后面跟自定义函数的自定义命令的名称

image-20250311194528732

这就是定义自定义函数的方式,这里的main就是函数名,void是返回类型,开始和结束花括号之间的这部分是函数体,是这个函数执行时应该执行的代码。

在这里插入图片描述

按需调用这个函数代码,将执行这个函数。定义了函数,在代码其他地方,可以调用他们,

image-20250311195302599

将函数runapp放到main函数的函数体中

新的错误,找不到这个函数,你必须告诉你的程序runapp来自flutter

image-20250311195349857
在这里插入图片描述

这里flutter已经作为依赖添加了。

使用import添加导入路径,使其能找到runapp函数,

image-20250311200110535

理解函数、调用函数和函数定义以及flutter应用如何启动非常重要。

四、如何启动flutter应用程序

main()函数到底是如何执行的呢?

image-20250311200850873

函数可以被定义,但他们必须被调用,被执行才能真正运行他们定义中的代码。

如果只是定义了一个函数,而从来没有在函数内部调用过它,那么实际上不会被执行。

image-20250311201033978

main函数是dart中的一个特殊函数。这也是为什么上面这些奇怪的指令会自动添加到代码编辑器中,因为main函数是dart应用程序的主要入口点。

准确的说,是main.dart文件中的主函数,当应用程序在设备上激活时,

它将由dart自动执行,因此,在代码被解析和编译之后,当它在设备上执行时,main函数的编译版本会通过dart在该设备上自动执行,

因此不需要手动调用main,在main函数中,调用runapp函数,因为只是激活flutter app或启动flutter app并在屏幕上绘制一些用户界面的另一个重要步骤,因为runapp会告诉flutter在屏幕上显示什么。

五、理解小部件

现在有一个错误,需要一个位置参数

image-20250311201841674

image-20250311202320546

可以在源代码中看到runapp被定义为期望一些输入值,这就是括号之间的部分,可以指定函数正确工作所需的输入值列表。

有些函数不需要任何输入,比如main,其他函数会这样做,这些输入值称为参数或实参。定义函数时或调用函数时称为参数。

runApp知道什么显示在屏幕上?它需要的输入值就是应该在屏幕上显示的内容。

对于运行的应用程序,需要一个小部件或小部件树作为值,因为flutter的用户界面是用小部件构建的。当构建一个flutter应用时,不会使用一些可视化的拖放编辑器,而是使用小部件在代码中构建用户界面,通常将许多小部件相互组合,将这些小部件相互嵌套来构建界面。由于将小部件嵌套在一起,实际上最终会得到一个小部件树,在这个树的顶部有一些根小部件,然后可能是一个子小部件和另一个子小部件,然后可能会包含多个子小部件。

image-20250311203412921

image-20250311203919353

flutter用户界面是通过组合和嵌套小部件来创建的,例如,通过添加文本小部件,这是flutter提供的在按钮小部件内部的屏幕上显示文本的功能,使按钮具有一些文本。flutter提供了许多内置的小部件可以在代码中使用,如按钮,表单输入,布局小部件,也可以构建自定义小部件。

六、使用第一个小部件并将值传递给函数

官方widgits:https://docs.flutter.dev/ui/widgets

image-20250311205358972

现在我们调用MateriaApp,在某种程度上它就像一个函数,但它实际上是一个所谓的类或类的构造函数。MateriaApp几乎在所有要构建的flutter应用中使用,因为这是用作起点的主要小部件。最后传递给runApp,MateriaApp这个主部件为用户界面做了很多幕后的设置工作,确保了界面可以正确地显示在屏幕上,但现在屏幕上什么都没有显示,需要向MateriaApp传递另一个参数,以在屏幕上显示某些内容。

当调用MateriaApp时,我们正在创建这样一个应用小部件,告诉flutter在屏幕上显示这个MateriaApp()小部件,这是UI的一部分,不管它是什么,都是传递给runApp的值。

image-20250311210356161

将输入值传递给函数,以便函数可以对这些输入值执行某些操作,是编程的关键部分。

七、位置参数和命名参数

在这里插入图片描述

MaterialApp还需要一个输入值,用来定义应用程序UI中应该显示的内容,MaterialApp没有太多的信息来运行应用程序,屏幕上该显示什么

image-20250312193601968

函数可以接受多个逗号分隔的参数,然后传入值并按位置匹配。调用函数时提供给该函数的第一个值将映射到第一个参数,第二个值将映射到第二个参数
在这里插入图片描述

在定义函数的代码中,命名参数用花括号{}括起来,与位置参数或实参相比,区别在于调用函数时传递值的顺序并不重要,而是通过名称来标识这些参数。这正是MaterialApp在内部实现的方式,有一个很长的命名参数列表用花括号括起来了所有的这些参数,这些参数就被简单的命名了。

image-20250312193155204

image-20250312194301181

home命名参数很重要,这是必须为MaterialApp设置的主要参数,用于定义哪种widget哪种UI元素应该显示在传递给运行app的应用UI中。

image-20250312194509414

通过内置的文本小部件来显示一些文本,也跟MaterialApp一样,文本小部件来自于flutter由flutter团队提供。

八、组合多个小部件

把鼠标悬停在文本小部件上,它实际上也接受一些命名参数。{}之间的一长串参数,也有一个位置参数,在这里,data这个位置参数确实是我们在使用文本时必须设置的。定义函数时,可以根据需求混合匹配这些不同的参数类型。
在这里插入图片描述

传递一段数据是可读的文本,文本用单引号或者双引号括起来。单引号更常见。

image-20250312200209754

我们有了第一个基本的小部件组合,创建了文本小部件,并将其传递给MaterialApp,然后传递给runApp。

image-20250312200527658

如果有模拟器在运行,可以通过两种方式来运行看看效果。

image-20250312200630591

九、理解const值

得到了第一个屏幕输出,第一个基本UI。

image-20250312201036244

蓝色的曲线证明没有错误,但是有一些改进的空间,代码不是最佳的。

image-20250312201207660

建议应该在构造函数中使用const来提高性能。

image-20250312201350140

const是一个关键字,可以通过颜色来判断,它与void和import颜色相同,是内置在dart语言中的关键字,const是一个关键字和一个功能,用于帮助dart优化应用程序运行时的性能。

如果你讲某个东西标记为const,比如在应用程序中使用的一个文本小部件,那么这个文本小部件将存储在运行应用程序的设备的内存中,无论你是否使用const,一旦你的代码执行了你的代码所创建的东西,比如小部件,就会被存储在设备内存中。但是使用const,当你在应用程序中第二次使用相同的小部件或相同的文本时,现有的内存对象将被重用,而不是创建第二个内存对象。使用const允许dart重用相等的值,并避免内存中的数据重复,从而让应用程序更具有内存效率并提高整体性能。

cosnt Text('Hello World!')

现在并不用记住需要在哪个小部件前加const,代码编辑器会告诉你哪些地方要添加和删除。例如我在文件小部件前也添加,会告诉我删除,因为MaterialApp前已经添加了。

image-20250312202655879

十、构建更复杂的部件树

怎么让界面变得漂亮呢?为了让它变得更漂亮,必须添加更多的小部件。另一个内建的小部件scaffold小部件可以帮助我们更好的实现这个功能,帮助我们在app中设置一个好看的屏幕。MaterialApp是根小部件,它对于设置整个app非常重要,但许多app由多个屏幕组成,这些屏幕也必须设置,即使在app中只有一个屏幕,就像我们这里看到的这样,这个屏幕必须设置为有一个漂亮的背景颜色,以便在它的子部件上强制一些基本的样式等等。

在这里,我们用scafflod小部件包装文本,scafflod必须在MaterialApp内部,但应该包装在属于屏幕小部件周围。

如果想知道哪个小部件需要哪种参数,可以将鼠标悬停在小部件上了解可接受的参数,body的值是应该在这个scafflod小部件中显示的小部件。

image-20250312204322736
在这里插入图片描述

运行一下:

image-20250312204658786

hello world可以在另一个小部件的帮助下实现在屏幕上居中,

用一个部件小部件center来包装文本,

image-20250311203919353

除了手动添加外,还可以右击文本小部件,点击重构,会得到一些重构建议,编程中的重构就是改变你现有代码的过程。

image-20250312205752267

点击使用center小部件来包装文本小部件

image-20250312205830005

将自动创建center小部件,并将文本小部件传递给center小部件的命名子参数。

在这里插入图片描述

现在这行代码越来越长,但这仍然是一个简单的小部件树,为了让代码易于阅读和维护,使其更有结构性,dart提供了一个很好的技巧来帮助格式化小部件树,在每个右括号后面添加逗号,除了最后一个需要分号的地方。

image-20250312210845886

image-20250312211000512

运行格式化文档命令,点击或使用快捷键,现在更易于理解这个小部件树,有了一些漂亮的缩进,可以显示哪个小部件在哪个小部件的内部。

image-20250312211056761

保存一下代码看一下效果,如果没有更改,刷新重启一下

image-20250312211531433

可以看到文本在屏幕中央了,通过添加这两个内置小部件,scafflod和center,再次改进了app。

image-20250312211616465

十一、了解值类型

类型是DART的一个重要的基本概念,dart是一种类型安全语言,意味着使用的所有值都是某些类型。例如字符串,int。

image-20250313194544654

每个值不仅仅有一个类型,通常有多重类型。例如,多有的值至少都是对象类型,然后它们也有更具体的类型。这些类型内置在dart中,或由第三方包提供,或由在创建自己的类型时提供。

image-20250313194654493

鼠标放在hello world上,可以看到代码编辑器显示的信息,该值的类型。

image-20250313195027110

app函数参数信息前面

image-20250313195211020

为什么会有这种类型的特征呢

它存在,并且由dart强制执行,确保永远不会意外的在错误的地方使用错误的类型,例如text文本小部件只处理字符串,不然会报错:

image-20250313195600855

image-20250313195659130

image-20250313195901298

data是参数名,前面的注释是该参数所期望的类型。

例如自定义一个函数,参数为int数字类型,如果你向这个函数传递一些文本,你会得到错误:

image-20250313200152161

例如runapp函数需要一个小部件作为它的第一个也是唯一的参数,

image-20250313200426321

widget类型的值,结果证明,materialapp也就是传递给runapp的值,就是这样一个小部件

这就是类型背后的思想,在dart中,类型无处不在,而不仅仅是在函数的参数列表中。例如main前面的void也是一个类型,它是main函数的返回值类型。

image-20250313200851178

可以自己构建类型,也可以通过第三方软件包获得许多类型,还有一些dart内置的核心类型:

image-20250313201018448

十二、配置小部件和了解对象

把背景颜色从白色变成一个漂亮的渐变色,同时改变文字

scaffold小部件,除了设置body参数在scafflod内部显示的小部件外,还可以设置其他scaffold支持的参数,例如颜色

image-20250313201619725

大多数小部件都允许将值传递给不同的参数,有一些需要小部件的参数,也有一些参数不需要小部件,而是允许配置或样式化该小部件,例如scaffloid。

在其中添加新行并按下Ctrl+Space,可以看到支持的多种参数

注:Ctrl+Space用于触发代码补全、智能提示等功能,这个快捷键在某些操作系统或输入法设置下可能与系统功能(如输入法切换)产生冲突,导致无法正常工作,可以修改快捷键以解决冲突,我使用的是Ctrl+Alt+Q。

image-20250313204001300

例如背景颜色参数,允许你设置scafflold创建的背景颜色

image-20250313204144996

现在backgroundcolor参数需要一个color类型的值

image-20250313204528089

现在你已经了解了类型,知道参数名称前面的内容是类型定义。

color?表示颜色或者为空值null

image-20250313204744564

颜色值可以使用内置的颜色类或者构造函数来创建。

MaterialApp、Scaffold、Center、Text是小部件,但从技术上讲,这里调用的函数在代码中称为构造函数,这里可以使用color构造函数来创建一个颜色的东西

image-20250313205146089

也可以使用特殊颜色,colors. 不用加括号,而是用点来访问预定义颜色的列表

image-20250313205425935

image-20250313205509819

运行:

image-20250313205604699

鼠标悬停在颜色上,会有一个颜色选择器,可以用它来更方便的选择一个颜色。

image-20250313205655293

image-20250313205900033

image-20250313210111639

fromARGB的函数,给它一个颜色类型的值

这里不是内置在dart中的类型,而是由flutter提供的类型。

所有的值都是一个对象。

image-20250313210242153

flutter中的小部件也只是对象。
在这里插入图片描述

最后,它们是对象,对象是dart中的基本值,

所有其他值最终也是对象,而对象只是内存中的数据结构,在运行app的设备上,这就是dart在内存中保存值的简单方式。

image-20250313210316833

对象是dart中的核心概念,所有的值最终都是对象,有简单的对象,比如‘hello world’这个文本,也有复杂的对象,比如这个颜色对象或小部件对象、materialapp、scaffold。最终,所有都只是由dart管理的内存中的数据结构,这些数据结构也可以一起工作。

image-20250313210346172

例如backgroundcolor需要一个颜色对象,以便在scaffold小部件对象能够接受到该颜色对象,并使用存储在该颜色对象中的颜色信息来制作该用户界面的背景颜色,所以都是对象。

image-20250313211548321

小部件也只是对象,只是flutter中特殊类型的对象,

所有的这些对象都在一起工作,将最终的用户界面带到屏幕上。

使用flutter构建app时,总是会有许多对象一起工作,比如有嵌套在其他小部件中的小部件,但也有这个颜色对象这样的配置对象由小部件使用。

以上就是添加背景颜色的方法,帮助我们意识到dart应用程序中对象的重要概念。

十三、使用配置对象(非部件对象)

现在不能用背景颜色来实现,而且scaffold也没有其他参数可以设置一个渐变背景。

可以在scaffold和center之间添加另一个新的小部件,右键单击center并重构来包装center,从而也隐含的包装text。
在这里插入图片描述

用容器来包装它,这是flutter提供的一个小部件。它对于配置样式和布局设置非常有用。

image-20250313212858817

添加后得到的错误

image-20250313212935962

container它不支持设置为const,不能将这个小部件树中更高的一些父部件设置为const。

蓝色波浪线告诉我们没必要设置容器,因为不配置容器没有任何改变。

image-20250313213303377

image-20250313213208327

ctrl+space,容器部件提供了一个装饰参数,允许添加各种装饰到容器,也就是容器中的子元素。

image-20250313213351798

现在decoration想要一个decoration的参数,可以用内置的BoxDecoration构造函数

image-20250313213640219

image-20250313213810747

image-20250313213952216

BoxDecoration类型

调用BoxDecoration函数来构造BoxDecoration对象,还支持各种可以设置的参数。例如gradient梯度参数,然后需要一个gradient类型的值

image-20250313214455408

例如LinearGradient,这是另一个创建线性梯度的构造函数,它也是Gradient类型,这个LinearGradient需要更多的参数,

image-20250313214607495

我们现在做的通常会将小部件或配置对象嵌套在一起,以便一起运行来提供所需的整体用户界面。

image-20250313215148170

十四、泛型,列表和添加渐变颜色

image-20250315154931959

鼠标悬停在colors这个参数上面,可以看到List,意味着它需要一个值列表,不仅仅是一个值,而是多个值,这就是dart中的列表,多个值的集合。这里颜色参数的类型定义是一种特殊的dart语言,泛型类型。泛型类型只是一种与其他类型一起工作的类型,但对于可以提供的确切类型是灵活的。比如,list是内置在dart中的一种非常灵活的类型,根据你的用例,可以拥有其他对象的字符串列表,当定义列表的类型时,尖括号之间的类型定义了列表中可能存在的值的类型。

image-20250315155955909

image-20250315161553555

设置const,dart可以存储这些对象这些值并重用,如何在代码其他地方使用,以利用这种内存使用优化,提高app的性能。

image-20250315161621909

十五、如何配置小部件和对象

渐变默认是从左到右,现在我想要左上角到右下角的渐变,可以向LinearGradient添加更多的参数来实现。

image-20250315162109559

可以通过设置坐标

image-20250315162244353

或者不使用坐标,使用.表示法来访问一些预定义的值

image-20250315162823865

如何知道这些预定义值的用法,

第一种:需要提供一个值时,按下建议快捷键(ctrl+space),我这里自定义为ctrl+alt+Q。可以获取一些建议,建议菜单非常智能,基本上前三个已经是有帮助的建议。

image-20250315163118088

第二种,查看官方文档

搜索正在使用小部件的名称,flutter LinearGradient

在这里插入图片描述

在官网文章可以知道使用该小部件货配置对象或其他任何内容的更多信息

十六、练习文本样式

现在已经开始使用一些样式选项,现在来设置文本的样式。设置文本的颜色和大小。

巧用帮助快捷键

image-20250315170244783

如果想设计一些东西或者改变一些小部件的配置,第一步先看看是否有一些参数可以设置。

image-20250315165922064

image-20250315165849886

十七、自定义小部件,为什么需要它们

代码越来越多,构建flutter app时通常将大部件树分开并构建自己的部件,将代码拆分为多个较小的可能可重复使用的构建块,一般来说,涉及到分解小部件树和提取自定义小部件没有一种正确或错误的方法,取决于你想把哪些小部件放入自定义小部件。

这里可以把Container容器部件放入自定义部件,使用这个容器及其所有设置和所有子部件,选中的这部分放到一个单独的小部件,因为可以使用这个容器有一个背景渐变应用到app的其他地方,这样我们就有了可重用的预购容器,这里可能只使用一次,但更大的app中可能有多个屏幕,在不同的屏幕或app的不同部分重用某些小部件。即使没有重用,拆分小部件树将Container放入一个单独的小部件也可以提高整体代码的可读性和可维护性。

image-20250315171939703

如何将其放入一个单独的小部件中,需要使用dart中的内置类class关键字来创建一个类。

十八、理解类

小部件是对象,而对象是内存中的这些数据结构。

image-20250315173554973

不仅小部件是对象,所有值的类型也是对象。

image-20250315173704228

因此所有值的类型也是内存中的这种数据结构。

这就是为什么对象概念是dart中的一个关键概念。

image-20250315173815502

类与对象的概念密切相关。

理解dart是一种面向对象的语言。因为每个值都是一个对象。

image-20250315174005690

一些简单的值,如文本或数字,但代码中也有更复杂的值,比如小部件,配置对象。

比如允许配置渐变的LinearGradient对象或单个颜色的对象。

image-20250315174551929

image-20250315174651543

这些更复杂的值是在类的帮助下创建的,dart中的类是对象的蓝图。

image-20250315175447612

为什么需要这样的蓝图?

对象是内存中的数据结构,那这些数据结构里面有什么?答案是数据,即变量或属性,例如登陆用户的用户名或者渐变所选的颜色;还有函数或在对象上下文中通常称为方法。所以对象是组织数据和分离逻辑。处理某些数据的逻辑通常与该数据位于同一对象中,而不是位于代码中的其他对象或其他位置。哪个对象提供哪些功能取决于对此对象的定义。这就是类重要的地方,有了类,你就定义类它。定义在运行时创建对象时将存储哪种类型的数据,并定义哪些额外的函数(方法)可以存储在这样的对象中。

image-20250315175852227

image-20250315181639475

在这里插入图片描述

这些东西都有类作为blueprints。

正如官方文档看到的那样,这些都是flutter中内置的蓝图,可以在代码中使用它们来创建基于这些蓝图的对象。

image-20250315181911336

所以在代码中,最终使用的是类和它们的构造函数。

当app在设备上运行,代码从上到下执行,实际的对象被创建并存储在内存中。

随意这些内置的小部件,配置对象,最终都是类,通过像函数一样执行,将其转换为对象。通过调佣它们的构造函数,这个过程也称为类实例化或对象实例化。正在实例化一个类,正在创建一个基于类的对象,这就是自定义小部件也是类的原因。内置的小部件被定义为类,还可以将自定义小部件定义为类。

十九、构建自定义小部件

现在知道类所有的东西都是对象,并且这些对象都是基于类构建的。

类名应该遵循一般规则,并且还应该描述类的内容。

image-20250315204533931

类可以扩展其他类,可以从其他类继承功能、数据和逻辑,通过extends关键字来完成,dart中的内置关键字。

继承StatelessWidget,来自flutter框架的类。

image-20250315204728554

StatelessWidget自动为GradientContaine这个类添加大量逻辑和数据,无需在花括号之间编写任何内容。它添加了flutter所需的大量数据和逻辑,以便将其用作小部件并将其添加到Ui中。

没有在自己的类中实现我应该实现的所有内容,缺少一个名为build的方法。

image-20250315205127246

把函数添加到类中,把这些函数称为方法。

image-20250315205632361

绑定这个类和这个构建方法返回一个Widget,函数名前面的是函数的返回值类型

在这里插入图片描述

还应该在构建方法前添加一个注释,override,明确表明覆盖了StatelessWidget的方法。

除了添加类型和添加重写外, build还必须接受参数。

花括号中间添加函数体,要做的是返回一个小部件,应为build的返回类型是Widget

void也是函数的返回类型,内置在dart中的一个特殊值,意味着没有任何要返回的类型

image-20250315210636632

在应该返回值的函数或方法内部,使用return关键字+想要返回到值。当一个函数或方法使用return关键字返回一个值时,该值将在调用该函数的地方可用。

返回Container小部件及其所有配置和子小部件。

image-20250315211152097

image-20250315211607467

二十、使用构造函数

公共小部件的构造函数应该有一个key参数

image-20250315211905572

通常不需要添加构造函数,会自动得到一个,但如果要在创建这个小部件的时候添加一些额外的设置或配置,必须添加自己的构造函数。

只需要重复类的名称,像一个方法一样添加,只是没有返回值。在这里可以做一些初始化工作。

用两个正斜杠添加注释文本,注释文本不会被解释为代码,但可以帮助其他开发人员理解代码。

image-20250315212657405

通常不需要添加花括号

函数中通过花括号来接受参数

要将key这个参数转发给StatelessWidget,可以在构造函数名和圆括号后面加一个冒号,就可以做一些变量初始化的工作。

image-20250315213343695

通过内置在dart中 关键字super,像函数一样执行来访问你继承的父类,把StatelessWidget中命名的参数key设置为构造函数GradientContainer中的参数key

image-20250315213837912

dart也提供了一个快捷方式

super.key,接受一个名为key的命名参数,并将自动转发给父类

image-20250315214253011

常量构造函数

image-20250315214339464

image-20250315214407968

用自己的构造函数自定义自己的类时,在前面加const,以告诉dart这是一个可以优化的类,可以存储在内存中以便重用

image-20250315214651485

二十一、跨文件拆分代码

除了构造函数,在使用类时还应该将它们放入单独的文件。以保持每个文件袋可读性和可维护性,使文件相对精简,不会包含无止境的代码量。

在lib文件夹添加一个新文件,命名gradient_container.dart。

遵循命名方式,所有的小写多个单词,用_来分割

image-20250315215515672

这些部件时未知的,在未导入flutter包时会报错。
在这里插入图片描述
在这里插入图片描述

dart不会自动扫描和连接项目中的所有文件,必须使用import关键字来考虑文件之间的任何连接。

image-20250315220142584

二十二、练习创建自定义小部件

将文本样式小部件创建自定义小部件

image-20250315221712689

image-20250315222434071

image-20250315222511880

二十三、引入变量

什么是变量?

变量是数据容器,在var关键字的帮助下创建,然后是赋值运算符等号,然后是应该存储的值。定义一次,在代码的任何地方多次使用。

image-20250316142124903

在渐变容器中,在开头定义对齐方式,在文件开头完成,就不用深入到小部件树中。

变量名以小写字符开头

变量的值可以可变,不能保证它是稳定的,所以在BoxDecoration前我们不能告诉dart可以缓存和重用该值,需要去掉const,因为这些变量没有锁定,可能会发生变化,重复使用此值是不安全的,dart可能会意外的重复使用过时的值

image-20250316143958508

image-20250316144528244

二十四、变量和类型-结合两个关键概念

变量也有类型

dart能推断出变量的类型

image-20250316144753660

如果最初没有赋值,dart不知道这个变量的类型,推断的类型将是动态类型(dynamic),dart中的一种特殊类型,会接受所有值类型。

image-20250316145127247

通常要避免这种情况,没有类型信息可能会导致app的错误,dart无法确保不会在错误的地方使用错误的类型。

在最初没有赋值的情况下,应将var关键字替换为存储在该变量中的类型的名称。?表示可以为null

image-20250316145739962

二十五、final & const -特殊类型的变量

有时候一些变量永远不会改变

image-20250316150129128

final是一个内置的关键字,意味着这个数据容器永远不会接受新值。

在有多个开发人员在代码上工作的团队中,尽可能的限制,确保一些同事不会意外的覆盖整个项目代码中其他地方的某个变量值。

实际上final是const的另一种用法,const可以创建常量变量或常量数据容器,几乎和final一样,const也确保类你不能重新分配这些变量。

不同的是,const告诉dart是常量,意味着只是在编译代码时被锁定。

但是如果是需要调用一个函数动态计算所需要的对齐,在app运行时执行此函数以获取实际对齐值,这个时候就用final,之后不会重新分配变量,但它不是编译时常量,在编译此代码时,getAlignment可能返回到值还不知道,只有在执行代码时才知道

image-20250316151345521

二十六、实例变量(属性)和可配置的小部件

使用变量特性来提高代码的可重用性,通过动态接收输入值来调整StyledText这个类,使其更易于重用。

image-20250316153333426

重用StyledText小部件时,总是会输出hello world。现在把输出的文本变成动态。

在GradientContainer小部件使用StyledText小部件时可以设置,小部件应该能从外部接受数据,通常都做法。从GradientContainer小部件内部将数据传递到StyledText小部件中

image-20250316153644373

在花括号里面输入更多的命名参数,或者在花括号前面添加位置参数

image-20250316154058738

添加位置参数,加上string参数类型

image-20250316154308805

如何使用这个位置参数?并不能在类中的其他方法直接使用,虽然在同一个类中名,但它们时相互分离的

image-20250316154430022

必须添加一个类变量,一个属性到这个类中

image-20250316154904946

确实有了这个变量,但这个变量仍然没有设置为作为位置参数接收的值,可以这样:

image-20250316155307525

DART给了一种快捷方式,这是一个常见的模式,在参数上接受一个值,并希望将其存储在该类的变量中,在自己的类中接收、存储和使用值。

image-20250316155658326

this.text,查找一个名为text的变量(自动在类中查看一个同名的变量),并设置它等于这里接受到的参数值,这个构造函数接受的第一个参数,this时dart提供的关键字,这个关键字在类内部使用,用来引用类本身或者引用基于类构建的对象。在这里可以使用它来告诉dart我们想要访问这个类中定义的文本变量。

this.text告诉dart不只是想接受这个text位置参数,而是它应该自动映射到一个同名的类变量

image-20250316161342124

在变量类型前面添加final,任然希望清楚哪种类型的值将存储在这里,明确这只会被接收到的参数设置一次,并且此后不会被更改,一旦初始化,就可以保证始终是同一个对象,可以被dart缓存和重用,这就是接收参数并存储它们的方式。

在属于这些类的变量和基于这些类的对象中,实例化变量,重用不同的文本值的StyledText。以便文本本身不再在StyledText中硬编码。

image-20250316162152243

二十七、练习可重用的部件和构造函数

让GradientContainer更灵活,将颜色作为参数传递给GradientContainer

image-20250316163111242

方式一:位置参数

image-20250316164244254

image-20250316164312552

方式二:命名参数

默认情况下,命令参数是可选的,添加required表示不可选

image-20250316164517894

image-20250316173943597

image-20250316173924549

方式三:接收两种单独的颜色

image-20250316174531965

image-20250316174549579

二十八、显示图像和使用多个构造函数

目标是有一个按钮,可以按下它来掷骰子

下一步在屏幕上显示一些骰子图像

将图像文件添加到项目中

新建assets文件夹,再新建images子文件夹,把图像文件拖进来

image-20250316182624956

为了在代码中使用,还必须配置pubspec.yaml

找到注释掉的这部分

image-20250316182829832

指定包含图像的相对路径
在这里插入图片描述

image-20250316183725583

Image.asset(),使用资源构造函数

使用内置在dart中的一个特性,可以在给定的类中定义多个构造函数。

以上学习笔记只是这门课程中的冰山一角,在深入学习过程中,我整理了一份精选学习资料包,包含视频教程等,中文字幕。这些素材全部来源于网络公开渠道,仅供个人学习交流使用。

如果您希望获取这份资料,可以查看我分享的资源:Flutter & Dart 基础课程学习笔记分享
https://download.csdn.net/download/weixin_44692732/92052113?spm=1001.2014.3001.5503
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

http://www.dtcms.com/a/424126.html

相关文章:

  • 营销型企业网站系统模板下载建设网站前期准备工作
  • Android车机系统上电获取历史定位信息异常分析
  • 建设银行征信中心官方网站企业网站建设与推广多少钱
  • 如何利用开源库和安全芯片设计fido令牌
  • 全国信息网查询平台知名seo公司
  • 加强网站信息内容建设的意见最新网站制作公司哪个好
  • 橙域名网站网站开发天津网站开发
  • 学校网站推广方案凡科网h5
  • 网站建设xiu021网站域名备案注册证书查询
  • 建设网站政策风险百度推广优化师是什么
  • 深入理解MySQL_1 MySQL系统架构
  • C++之友元函数与前向引用
  • 01_系统架构设计
  • 解决 jenkins 用户 SSH 连接目标服务器时的 Permission denied 问题
  • 【html】canvas实现一个时钟
  • 怎么用支付宝做发卡网站优质的seo网站排名优化软件
  • 论文阅读四-第三章
  • 工程网站模板wordpress查看
  • openai代码研读:OpenAI Python SDK 中 AsyncOpenAI 类的定义
  • 广东公诚通信建设监理有限公司网站建设内容管理网站的目的
  • 乐平市网站建设企业运营数据分析报告
  • 一张草稿纸
  • GSPO论文阅读
  • 做设计去哪个网站找素材怎么推广效果好呢网站怎么做推广
  • 电子商务网站开发分几个模块wordpress阅读数
  • 做自媒体一般都注册几个网站网站建设的可用性
  • 南通网站快速收录网站备案 万网
  • 网站加速器免费永久企业网站 优秀
  • 做模板网站价格银川专业做网站
  • QML 核心概念:构建动态 UI