本文主要讲述新建一个Flutter项目的各个项目结构,并配合初始项目,来了解Flutter的各种状态,以及常用类解析
项目结构解析,以及各个文件的作用
新创建一个Flutter项目,项目接口如下图所示
.drat_tool
是Flutter
工具使用的一个临时目录,包含了一些工具生成的配置和构建输出。一般不需要开发者去修改,由Flutter
自动生成.idea idea
的配置信息,不用管android
存放Android
平台相关的代码和配置文件,一般需要修改的是AndroidManifest.xml
,用来配置权限和注册文件的build
编译文件 不用管ios
这个目录是用于存放iOS平台相关的代码和配置文件的lib
这个目录是主要的Dart目录,用来存放应用程序的逻辑和界面代码,大部分开发会在这个目录下进行linux
这个目录是用于存放Linux
平台相关的代码和配置文件的。它包含了一个Linux
项目的结构,其中包括CMake构建脚本和其他与Linux
相关的资源和配置文件。macos
这个目录是用于存放macOS
平台相关的代码和配置文件的。test
编写测试文件web
这个目录是用于存放Web
平台相关的代码和配置文件的windows
这个目录是用于存放Windows
平台相关的代码和配置文件的.gitignore
配置git
上传的.metadata
文件是由Dart
编译器生成的元数据文件。它包含有关项目的编译和依赖信息。遇到meadata
报错怎么办,嗯,删掉,让Dart
重新编译analysis_options.yaml
配置静态代码分析工具,可以在这里定义代码风格,金庸或启用特定的警告和错误检查之类pubspec.ymal
配置文件,用于声明项目的依赖关系、资源我呢见、版本号信息等,类似于Android
的build
文件ubspec.lock
自动生成,锁定项目的依赖关系
其中pubspec.yaml
是必需的,用于配置项目的依赖和资源,而pubspec.lock
和analysis_options.yaml
是根据需要自动生成的辅助文件,所以详细说一下pubspec.yaml
文件
pubspec.yaml文件解析
这一段需要配合 着代码看
name: untitled #项目名称
description: A new Flutter project. #项目描述
publish_to: 'none' #防止上传到pub.dev 这个类似与maven
version: 1.0.0+1 #版本号 前面是版本名字 +1是第一个版本
environment:
sdk: '>=3.0.1 <4.0.0' # 设置最低和最高版本
dependencies: #依赖文件 外部包
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
http: ^1.0.0 #把http 1.0.0版本导入项目
dev_dependencies: #开发时期的依赖包 通常是测试框架之类
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
flutter: #包含Flutter特定字段 ,比如配置
uses-material-design: true
assets:
- assets/
这一段把创建项目的注释去掉 翻译一下大概就是这个意思,值得注意的是flutter这个内容下uses-material-design
的意思是是 是否使用了Material Design 风格
,assets
下面这个表示把assets这个文件夹加载进去,一般就是系统资源,比如本地图片,如果在使用,必须先加载,我这里是把一个文件夹都加载了进去,当然也可以一个以额添加,路径copy
上去就可以
初始项目解析
在创建Flutter项目的时候有一个默认的计数器的Demo,我们就以此Demo来看一下他们分别有什么用
void main() {
runApp(const MyApp());
}
一个应用的入口,可以理解为Activity + 多Fragment形式,MyApp就相当于第一个Fragment,然后进入执行了MyApp一个类
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.orange),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
为什么要继承StatelessWidget
我当时也思索一段时间,也配合了文档和资料总结了一下,以下是我的理解:
常用的一般有StatelessWidget
和StatefulWidget
用来构建用户界面
StatelessWidget
是一个不可变部件,它的外观和交互在构建期间就确定了,不会发生变化,适用于那些不需要管理可变状态的部件,通常用于显示静态内容、接收用户输入并触发回调等简单场景。StatefulWidget
是一个可变部件,它可以根据内部的状态数据来改变外观和交互,适用于那些需要动态更新、管理状态的部件,例如表单输入、列表视图等。
也就是说主要看页面需不需要和用户互动,需要就用StatefulWidget
,不需要就用StatelessWidget
然后MaterialApp
是一个页面框架,可以设置主题,相当于Android的Theme,以及使用应用Material3
然后Home现在了一个MyHomePage
,这里又出现了一个const
什么意思呢,从经验来说一个常量,为什么要用常量来修饰小组件呢,因为小组件是不可变的,也就告诉编译器说这个小组件运行是不会发生变化,在重新渲染的时候可以直接使用,那MyHomePage
里面可能会有变化啊,这里指的变化是不会从MyHomePage
变成其他的Page
好的 来看下一段
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Image.asset('assets/icon.png'),
),
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
这里就相当于是显示的核心,等等为什么要分两个类写,我写个匿名内部类不完了吗,这里分开写的解释为最重要的一点性能问题,如果都写到一起,协程匿名内部类,当状态发生变化时,所有的外观和交互逻辑都会被重新构造和渲染,带来性能问题,分开写其他的好处就是,解耦啦,可读性啦,可重用性啦…..
分析完成之后学习以下控件吧
Scaffold
一个模板,就他把样式位置给你调整好,你写参数就完事Center
显示到界面中间 类似于Android FrameLayout
的gravity
Column
竖直盘列小组件 类似于Android LinearLayout
的vertical
padding
设置内边距 这个和Android
的View
不同,需要单独加一个小组件,而不是直接对View设置Text
用来显示文本,相当于TextView
没什么好说的FloatingActionButton
就是右下角的按钮Android
也有类似的,这里注意的是 定位是Scaffold赋予它到这个位置的,然后点击时间为onPressed
和onClick
一样,这里和Kotlin
的点击回调很类似啊,调用了一个_incrementCounter
方法
这里需要说一句 _incrementCounter
方法里面有一个setState
的方法 然后因为要告诉Flutter
我这个页面发生变化了,setState
就是这样的作用
总结
这一章算是学习了一下Flutter
的基础示例项目,因为本人也是Android
开发工程师,最近也是空闲时间比较多,所以有了学习Flutter
的念头,其中有问题的地方,麻烦大佬指出来,方便及时修改,在这里感激不尽,还有一个就是学习方式的问题,我可能比较喜欢配合着官方的示例项目一个一个来看,然后不懂了看文档,看别人写的文章,所以每一下子把小组件介绍完,那样我也记不住,另外Dart
语音和Java
很相似,又有一些Kotlin
的小玩意,因为本人是都学习还可以,所以不太吃力语言方面,不会的可以找Dart
语法看一看