Flutter基础概述

一、基础概念,参考资料

flutter主要发展方向为移动端跨平台方案。flutter的实现语言是dart,native端可支持的语言是安卓侧java、kotlin,ios侧oc、swift。
参考官网:
https://flutterchina.club/docs/
https://flutter.dev/docs

依赖仓库地址:
https://pub.dev/
这个地址有所有的dart依赖仓库,通知也托管所有的flutter公共依赖。

二、主要模块

  1. 基础语法
    在flutter中一切都是widget,包括基础组件,布局组件,样式组件,全部都用widget定义,这个带来了一些问题,样式和ui混合到了一起,如果自己团队没有设定一些约束,设定一些公用style,工程上显得比较混乱。
  • text
Text("我是一个text", style:TextStyle(fontSize:12,color:Colors(0xff333333)));
  • image
Image(image: AssetImage("images/my_image.png", package: 'my_package_name'));
Image(image: NetworkImage("https://xxx.xxx.xxx.png"));
  • button
Botton(
	onTap:()=>{//dosomething},
	image:Image.asset("xxxx.png"),
	title:Text("xxxx"),
);
  • 样式布局
Column(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.center,
            children:[
				Text(...),
				Button(...),
				Row(...),
			],
			padding:const EdgeInsets.fromLTRB(20, 30, 20, 20),
);
///	container
///	row
  1. 工程类型
    使用指令flutter create -t,可以创造一个仓库模板,仓库有几种类型,参考flutter create -h的说明,列举为下
  • app (default) Generate a Flutter application.
    主工程
  • module Generate a project to add a Flutter module to an existing Android or iOS application.
    如果想把flutter代码加入已有的Android、iOS工程下,可以使用这个仓库模板
  • puglin Generate a shareable Flutter project containing an API in Dart code with a platform-specific implementation for Android, for iOS code, or for both.
    包含Android或者iOS实现的仓库
  • package Generate a shareable Flutter project containing modular Dart code.
    仅包含dart代码的仓库,这个仓库可以创建.android和.ios两个隐藏文件夹作为运行环境,进行测试
  • skeleton Generate a List View / Detail View Flutter application that follows community best practices.
    未使用过
  1. 状态管理
  • StatelessWidget和StatefulWidget
    不需要做变更的组件,使用StatelessWidget即可。
    可能有状态变化的组件,使用StatefulWidget。
	class VariedWidget extends StatefulWidget {
	  @override
	  State<StatefulWidget> createState() {
	    return VariedState();
	  }
	}
	
	class VariedState extends State<VariedWidget> {
	  String _state = "before";
	
	  @override
	  Widget build(BuildContext context) {
	    return Column(
	      children: [
	        Text(_state),
	        TextButton(
	            onPressed: () => {
	                  setState(() {
	                    _state = "after";
	                  })
	                },
	            child: Text('点击改变状态'))
	      ],
	    );
	  }
	}
  • 共享状态管理Provider
  • 状态管理框架介绍
    Provider是官方解决多个组件共用状态的方案,了解它也可以帮助我们理解其它第三方的状态管理框架
    上述两点一同参考我编写的文档
    https://docs.qq.com/doc/DRUxseWhXQ2FZWHdi
  1. 路由管理
  • navigator
    官方基础方案,查看Navigator.dart了解更多细节。官网示例:
	import 'package:flutter/material.dart';
	
	// ...
	
	void main() => runApp(const MyApp());
	
	// ...
	
	class MyApp extends StatelessWidget {
	  const MyApp({Key? key}) : super(key: key);
	
	  @override
	  Widget build(BuildContext context) {
	    return MaterialApp(
	      title: 'Flutter Code Sample for Navigator',
	      // MaterialApp contains our top-level Navigator
	      initialRoute: '/',
	      routes: <String, WidgetBuilder>{
	        '/': (BuildContext context) => const HomePage(),
	        '/signup': (BuildContext context) => const SignUpPage(),
	      },
	    );
	  }
	}
	
	class HomePage extends StatelessWidget {
	  const HomePage({Key? key}) : super(key: key);
	
	  @override
	  Widget build(BuildContext context) {
	    return DefaultTextStyle(
	      style: Theme.of(context).textTheme.headline4!,
	      child: Container(
	        color: Colors.white,
	        alignment: Alignment.center,
	        child: const Text('Home Page'),
	      ),
	    );
	  }
	}
	
	class CollectPersonalInfoPage extends StatelessWidget {
	  const CollectPersonalInfoPage({Key? key}) : super(key: key);
	
	  @override
	  Widget build(BuildContext context) {
	    return DefaultTextStyle(
	      style: Theme.of(context).textTheme.headline4!,
	      child: GestureDetector(
	        onTap: () {
	          // This moves from the personal info page to the credentials page,
	          // replacing this page with that one.
	          Navigator.of(context)
	            .pushReplacementNamed('signup/choose_credentials');
	        },
	        child: Container(
	          color: Colors.lightBlue,
	          alignment: Alignment.center,
	          child: const Text('Collect Personal Info Page'),
	        ),
	      ),
	    );
	  }
	}
	
	class ChooseCredentialsPage extends StatelessWidget {
	  const ChooseCredentialsPage({
	    Key? key,
	    required this.onSignupComplete,
	  }) : super(key: key);
	
	  final VoidCallback onSignupComplete;
	
	  @override
	  Widget build(BuildContext context) {
	    return GestureDetector(
	      onTap: onSignupComplete,
	      child: DefaultTextStyle(
	        style: Theme.of(context).textTheme.headline4!,
	        child: Container(
	          color: Colors.pinkAccent,
	          alignment: Alignment.center,
	          child: const Text('Choose Credentials Page'),
	        ),
	      ),
	    );
	  }
	}
	
	class SignUpPage extends StatelessWidget {
	  const SignUpPage({Key? key}) : super(key: key);
	
	  @override
	  Widget build(BuildContext context) {
	    // SignUpPage builds its own Navigator which ends up being a nested
	    // Navigator in our app.
	    return Navigator(
	      initialRoute: 'signup/personal_info',
	      onGenerateRoute: (RouteSettings settings) {
	        WidgetBuilder builder;
	        switch (settings.name) {
	          case 'signup/personal_info':
	          // Assume CollectPersonalInfoPage collects personal info and then
	          // navigates to 'signup/choose_credentials'.
	            builder = (BuildContext context) => const CollectPersonalInfoPage();
	            break;
	          case 'signup/choose_credentials':
	          // Assume ChooseCredentialsPage collects new credentials and then
	          // invokes 'onSignupComplete()'.
	            builder = (BuildContext _) => ChooseCredentialsPage(
	              onSignupComplete: () {
	                // Referencing Navigator.of(context) from here refers to the
	                // top level Navigator because SignUpPage is above the
	                // nested Navigator that it created. Therefore, this pop()
	                // will pop the entire "sign up" journey and return to the
	                // "/" route, AKA HomePage.
	                Navigator.of(context).pop();
	              },
	            );
	            break;
	          default:
	            throw Exception('Invalid route: ${settings.name}');
	        }
	        return MaterialPageRoute<void>(builder: builder, settings: settings);
	      },
	    );
	  }
	}

参考api:https://api.flutter.dev/flutter/widgets/Navigator-class.html,基本上大多数常用的路由需求都可以解决,不过有一个缺点就是每一次使用都需要传入context,部分框架可以解决这个问题。

  • 路由框架介绍
    GetX可以作为一个比较快速的路由封装工具,建议可以加上跳转native页面的封装。
  1. 网络请求
  • http
  • dio框架介绍
  1. 国际化、主题管理
  • 基础用法
    国际化:https://flutterchina.club/tutorials/internationalization/
    主题管理:使用Provider即可
  • 使用框架GetX
    GetX也具有国际化和主题管理能力。参考:https://github.com/jonataslaw/getx/blob/master/README.zh-cn.md
  1. 自定义组件
  1. 代码规范
  • 命名规范
  • 分包规范
  • 引用规范
    参考:https://github.com/alibaba/flutter-go/blob/master/Flutter_Go%20%E4%BB%A3%E7%A0%81%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83.md
    https://dart.cn/guides/language/effective-dart/style
  1. 单元测试
  • dart测试
  • widget测试
  • 集成测试
    参考:https://flutterchina.club/testing/
  1. 构建打包
    参考:https://flutterchina.club/android-release/

三、空安全介绍

dart空安全是一种约束,如果某个依赖不支持空安全,那么整个项目也无法使用空安全的形式构建。所以为了让项目可以使用空安全特性,就要求整个项目所有依赖,都遵循空安全约束。

四、dart带来的一些特点和约束

  1. 拓展方法
    extension关键字可以给已有的类,添加新的方法
  2. 因为flutter为了减少构建包的体积,所以未直接建立依赖关系的类,都会在构建中剔除,而反射可以引用到所有的类,flutter做的取舍就是禁用了dart的mirror库。
  3. 类型推断的疑问
    使用泛型时,如果某个参数要求使用指定的t extends xxx,那么直接传入xxx,似乎也会报错,很奇怪的特点
  4. 资源路径的管理
    image加载资源图片时,最好不要用绝对路径,而是用package指定包名,然后使用相对路径。不然在不同的路径引用,会显示不出图片。

五、flutter开发带来的感受

因为热加载可以实时刷新页面显示,所以开发页面非常的快速。
但是不是所有代码的调整都支持热加载,比如嵌套根App widget类的变更(这点和rn一样),比如资源的变更。

flutter没法使用反射,所以解析json类,显得格外繁琐。一般都是利用插件或者工具,自动生成解析代码。

flutter和rn一样解决了跨平台的问题。写一遍业务,可以应用到两端,减少了开发时间和测试压力。

但是我觉得rn对比flutter是有优势的。
两个方案实现的原理不一样,
RN是利用虚拟dom,映射成native组件页面来实现跨平台。
flutter是dart引擎下,自己渲染所有的页面实现跨平台。

  1. rn对原生的兼容性更好,做native的自定义组件时非常有优势。可以完美兼容所有的native组件。
    而flutter嵌入原生view,还存在很多bug,比如软键盘没法监控弹出等。

  2. 而且rn社区应该更加庞大,因为react只要是前端就很容易掌握书写。而flutter需要单独学习dart语法,虽然dart很简单,但是dart中也有很多反直觉的约束,比如泛型的问题。

如果让我自己写项目,快速开发可能会选择flutter,但是作为一个想要长期支持的项目,不想出问题的项目,我会选择rn。

### Flutter 基础知识教程 Flutter 是一个由 Google 开发的开源 UI 框架,用于构建跨平台应用程序。它支持在 AndroidiOS、Web 和桌面平台上运行的应用程序开发。以下是 Flutter基础知识概述: #### 1. 项目结构 Flutter 项目的文件夹结构通常包括以下几个关键部分: - `lib`:包含应用的主要代码文件。 - `test`:存放单元测试和小部件测试文件。 - `pubspec.yaml`:定义了项目的依赖项、资产(如图片、字体等)以及其他元数据[^1]。 #### 2. 导入与导出 在 Dart 中,使用 `import` 和 `export` 关键字来导入其他库或导出特定功能。例如: ```dart import 'package:flutter/material.dart'; ``` 通过这种方式,可以访问 Flutter 提供的各种组件和工具[^1]。 #### 3. 变量与数据类型 Dart 支持多种变量声明方式,包括 `var`、`const` 和 `final`: - `var`:动态类型变量,类型在运行时确定。 - `const`:编译时常量,值在编译时必须已知。 - `final`:运行时常量,值只能被赋值一次。 基础数据类型包括 Numbers(如 `int` 和 `double`)、Strings、Lists、Sets 和 Maps 等。 #### 4. 函数 函数是 Dart 中的基本构建块,可以通过以下方式定义和调用: ```dart void greet(String name) { print('Hello, $name!'); } greet('World'); // 输出: Hello, World! ``` #### 5. 流程控制 Dart 提供了常见的流程控制语句,例如 `if-else`、`for`、`while` 等。以下是一个简单的例子: ```dart for (int i = 0; i < 5; i++) { print(i); } ``` #### 6. Widget 组件模型 在 Flutter 中,Widget 是构建用户界面的核心概念。每个 UI 元素都可以被视为一个 Widget,且这些 Widget 可以组合在一起形成复杂的界面[^2]。例如: ```dart class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('Flutter Demo')), body: Center(child: Text('Hello, Flutter!')), ), ); } } ``` #### 7. 列表组件 列表布局是 Flutter 应用中常见的需求。通过 `ListView`,可以轻松实现垂直或水平方向的列表展示[^4]。例如: ```dart ListView.builder( itemCount: 10, itemBuilder: (context, index) { return ListTile(title: Text('Item $index')); }, ) ``` #### 8. Dart 编程语言特性 了解 Dart 的一些核心特性有助于更好地掌握 Flutter 开发: - 高性能:Dart 被设计为一种快速执行的语言。 - 静态类型检查:支持静态类型系统,帮助开发者减少错误。 - 异步编程:通过 `async` 和 `await` 关键字简化异步操作。 - 自动垃圾回收:无需手动管理内存[^5]。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值