Flutter工程目录结构

  1. flutter_app
  2. -android -包含Android特定文件的Android子工程
  3. -bulid -AndroidiOS的构建产物
  4. -iOS -包含iOS特定文件的iOS子工程
  5. -lib -Flutter应用源文件目录
  6. - main.dart -程序运行入口文件
  7. -test -测试文件
  8. -flutter_app_demo.iml -工程配置文件
  9. -pubspec.lock -记录当前项目实际依赖信息的文件
  10. -pinspec.yaml -管理第三方库及资源的配置文件
  11. 除了Flutter本身的代码、资源、依赖和配置之外、Flutter还包含了AndroidiOS的工程目录。Flutter工程实际上就是一个同时内嵌了AndroidiOS原生
  12. 子工程的父工程。我们在lib目录下进行Flutter代码的开发。而某些特殊场景下的原生功能,则在对应的AndroidiOS工程中提供相应的代码实现。供对应的
  13. Flutter代码引用。Flutter会将相关的依赖和构建产物注入这两个子工程,最终集成到各自的项目中,而我们开发的Flutter代码,最终则会以原生工程的形式
  14. 运行。

工程代码

  1. 从简单示例中,从基础的组件、布局到手势的监听、再到状态的改变、Flutter最核心的思想
  2. 第一部分是应用入口、应用结构以及页面结构、可以帮助你理解构建Flutter程序的基本结构和套路、
  3. 第二部分是页面布局、交互逻辑及状态管理、能够帮你理解Flutter页面是如何构建、如何响应交互、如何更新的、

代码分析

  1. import 'pckage:flutter/material.dart'
  2. void main() => runApp(MyApp());
  3. class MyApp extends StatelessWidget {
  4. @override
  5. Widget build(BuildContext context) => MaterialApp(home:MyHomePage(title:'Flutter Demo'));
  6. }
  7. class MyHomePage extends StatefulWidget {
  8. MyHomePage{key key, this.title}):super(key: key);
  9. final String title;
  10. @override
  11. _MyHomePageState createState() => _MyHomePageState();
  12. }
  13. class _MyHomePageState extends State<MyHomePage> {
  14. Widget build(BuildContext context) => {...};
  15. }
  16. 在本例中、Flutter应用为MyApp类的一个实例、而MyApp类继承自StatelessWidget类,这也就意味着应用本身也是一个Widget、事实上、在Flutter中,Widget
  17. 是整个视图描述的基础、在Flutter的世界里,包括应用、视图、视图控制器、布局等在内的概念、都建立在Widget之上,Flutter的核心设计思想便是一切皆Widget
  18. Widget是组件视觉效果的封装、是UI界面的载体、因此我们还需要为她提供一个方法、来告诉Flutter框架如何构建UI界面、这个方法就是build
  19. build方法中,我们通常通过对基础Widget进行相应的UI配置、或是组合各类基础Widget的方式进行UI的定制化、比如在MyApp中,我通过MaterialApp这个Flutter
  20. App框架设置了应用首页、即MyHomePage、当然MaterialApp也是一个Widget
  21. MaterialApp类是对构建material设计风格应用的组件封装框架、里面还有很多可配置的属性、比如应用主题、应用名称、语言标识符、组件路由等。但是、这些配置
  22. 属性并不是本次分享的重点。
  23. MyHomePage是应用的首页、继承自StatefulWidget类、这代表着它是一个有状态的WidgetStateful Widget)。而_MyHomePageState就是它的状态、
  24. 虽然MyHomePageState类也是Widget、但与MyApp类不同的是、它并没有一个build方法去返回Widget、而是多了一个creatState方法返回MyHomePageState
  25. 对象、而build方法则包含在这个—_MyHomePageState类当中.
  26. StatefulWidget StatelessWidget的接口设计、为什么会有这样的区别、主要是因为Widget需要依据数据才能完成构建、对于StatefulWidget来说、其依
  27. 赖的数据在Widget生命周期中可能会频繁的发生变化、由State创建Widget、以数据驱动视图更新、而不是直接操作UI更新视觉属性、代码表达更精炼、逻辑更清晰。
  28. class _MyHomePageState extends State<MyHomePage> {
  29. int _counter = 0;
  30. void _incrementCounter() => setState((){_counter++;});
  31. @override
  32. Widget build(BuildContext context) {
  33. return Scaffold(
  34. appBar: AppBar(title: Text(Widget.title)),
  35. body: Text('You have pushed the button this many times:$_counter')),
  36. floatingActionButton:FloatingActionButton(onPressed: _incrementCounter)
  37. );
  38. }
  39. }
  40. _MyHomePageState 中创建的Widget Scaffold,是Material库中提供的页面布局结构、它包含了AppBarBody、以及FloatingActionButton
  41. AppBar 是页面的导航栏、我们直接将 MyHomePage 中的title属性作为标题可使用、body则是一个Text组件、显示了一个根据_counter属性可变的文本“
  42. You have pushed the button this many times$_counter'.floatingActionButton,则是右下角的带+号悬浮按钮、我们将_incrementCounter
  43. 作为其点击处理函数。
  44. _incrementCounter的实现很简单、使用setState方法区自增状态属性——counter.SetState方法是Flutter以数据驱动视图更新的关键函数、他会通知Flutter
  45. 框架、我这有状态发生了改变、赶紧刷新界面、而Flutter框架收到通知、会执行Widget的build方法、根据新的状态重新构建页面。
  46. 状态的更改一定要配合使用 setState、通过这个方法调用、Flutter会在底层标记Widget的状态、随后触发重建、如果只修改、不调用setState、Flutter框架
  47. 也不会感知到状态的变化、因此界面上也不会有任何改变、

image.png

  1. MyAppFlutter应用的运行实例、通过在main函数中调用runApp函数实现程序的入口、而应用的首页则为MyHomePage、一个拥有_MyHomePageState状态
  2. StatefulWidget_MyHomePageState通过调用build方法、以相应的数据配置完成率包括导航栏、文本及按钮的页面视图的创建。
  3. 当按钮被点击后、其关联的控件函数——incrementCounter会触发调用。在这个函数中,通过调用setState方法、更新_counter属性的同时,也会通知Flutter框架
  4. 其状态发生变化、随后、Flutter会重新调用build方法、以新的数据配置重新构建_MyHomePageStateUI、最终完成页面的重新渲染、
  5. Widget只是视图的'配置信息'、是数据的映射、是只读的、对于StatefulWidget而言、数据改变的时候、需要重新创建Widget去更新界面、就意味着Widget创建
  6. 销毁会非常频繁、
  7. Flutter对此进行了优化、其框架内部会通过一个中间层去收敛上层UI配置对底层真实渲染的改动,从而达程度降低对真实渲染视图的修改。提高渲染效率、而不是上层
  8. UI配置变了就需要销毁整个渲染视图树重建。
  9. Widget仅是一个轻量级的数据配置存储结构。重新创建速度非常快。
  10. Flutter采用声明式UI设计、只需要描述当前的UI状态(即State)即可、不同UI状态的视觉变更由Flutter在底层完成。声明式UI编程的好处是:可以让我们把
  11. 复杂的视图操作细节交给框架去完成、这样一来不仅可以提高我们的效率、也可以让我们专注于整个应用和页面的结构和功能。