原来Flutter代码是这样运行在原生系统的!快来了解Flutter标准模板,感受原生系统中Flutter的魅力!

news/2024/10/31 1:32:54/

通过Android Studio创建的Flutter应用模板,了解Flutter项目结构,分析Flutter工程与原生Android和iOS工程有哪些联系,体验一个有着基本功能的Flutter应用是如何运转的,从而加深你对构建Flutter应用的关键概念和技术的理解。

Dart只要理解基本编程概念(比如,类型、变量、函数和面向对象),并具备一定前端基础(了解View是什么、页面基本布局等基础),就可以和我一起完成计数器示例工程分析

Android Studio创建Flutter工程应用flutter_app。Flutter会根据自带的应用模板,自动生成简单计数器示例应用Demo。我们先运行此示例,效果如下:

图1:计数器示例运行效果

每点击一次右下角带“+”号的悬浮按钮,就可以看到屏幕中央的数字随之+1。

1 工程结构

了解Flutter工程与原生Android和iOS工程关系及这些关系是如何确保Flutter程序最终运行在Android和iOS。

图2:Flutter工程目录结构

除Flutter本身的代码、资源、依赖和配置,Flutter工程包含Android和iOS工程目录。因为Flutter虽然是跨平台开发方案,但却需要一个容器最终运行到Android和iOS平台,所以 Flutter工程实际是同时内嵌Android和iOS原生子工程的父工程:在lib目录进行Flutter代码开发,某些特殊场景原生功能,则在对应Android和iOS工程提供相应代码实现,供对应Flutter代码引用。

Flutter会将相关依赖和构建产物注入这两个子工程,集成到各自项目。而我们开发Flutter代码,最终以原生工程形式运行。

2 工程代码

Flutter自带的应用模板,即计数器示例,对初学者是极好入门范例。从基础的组件、布局到手势的监听,再到状态的改变,Flutter最核心思想在这60余行代码。

为便学习理解,删掉核心流程无关组件配置代码及布局逻辑,不影响示例功能的情况下对代码进行改写,并分两部分:

  • 应用入口、应用结构以及页面结构,理解构建Flutter程序的基本结构和套路
  • 页面布局、交互逻辑及状态管理,理解Flutter页面是如何构建、如何响应交互,以及如何更新

3 第一部分代码,应用的整体结构

import 'package:flutter/material.dart';void main() => runApp(MyApp());class MyApp extends StatelessWidget {Widget build(BuildContext context) => MaterialApp(home: MyHomePage(title: 'Flutter Demo Home Page'));
}class MyHomePage extends StatefulWidget {MyHomePage({Key key, this.title}) : super(key: key);final String title;_MyHomePageState createState() => _MyHomePageState();
}class _MyHomePageState extends State<MyHomePage> {Widget build(BuildContext context) => {...};
}

Flutter应用为MyApp类的一个实例,MyApp类继承自StatelessWidget类,即应用本身也是一个Widget。Flutter中的Widget是整个视图描述的基础,Flutter中的包括应用、视图、视图控制器、布局等概念,都建立在Widget之上,Flutter核心设计思想是一切皆Widget。

3.1 Widget

组件视觉效果的封装,UI界面的载体,因此还要为它提供一个方法,告诉Flutter框架如何构建UI界面,即build。

3.1.1 build方法

通过对基础Widget进行相应UI配置或组合各类基础Widget进行UI定制化。如MyApp通过MaterialApp这个Flutter App框架设置应用首页,即MyHomePage。

3.2 MaterialApp类

是对构建material设计风格应用的组件封装框架,有很多可配置属性,如应用主题、应用名称、语言标识符、组件路由等,可参考Flutter官方的 API文档,了解MaterialApp框架的其他配置能力。

3.3 MyHomePage

应用首页,继承自StatefulWidget类,有状态Widget(Stateful Widget), _MyHomePageState就是其状态。

虽然MyHomePage类也是Widget,但与MyApp类不同,它没有build方法返回Widget,而是多个createState方法返回_MyHomePageState对象,而build方法包含在这 _MyHomePageState 类中。

3.4 StatefulWidget V.S StatelessWidget的接口设计

因为Widget要依据数据才能完成构建,对StatefulWidget来说,其依赖的数据在Widget生命周期中可能频繁变化。由State创建Widget,以数据驱动视图更新,而非直接操作UI更新视觉属性,代码表达更精炼,逻辑更清晰。

4 第二部分-页面布局及交互逻辑

class _MyHomePageState extends State<MyHomePage> {int _counter = 0;void _incrementCounter() => setState(() {_counter++;});Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(Widget.title)),body: Text('You have pushed the button this many times:$_counter')),floatingActionButton: FloatingActionButton(onPressed: _incrementCounter));}

_MyHomePageState中创建的Widget Scaffold,是Material库提供的页面布局结构,包含:

  • AppBar,页面导航栏,直接将MyHomePage中的title属性作为标题使用
  • body,Text组件,显示了一个根据_counter属性可变的文本:‘You have pushed the button this many times:$_counter’。
  • floatingActionButton,页面右下角的“+”悬浮按钮。将 _incrementCounter 作为其点击处理函数

_incrementCounter

使用setState方法自增状态属性_counter。setState方法是Flutter以数据驱动视图更新的函数,会通知Flutter框架:我这儿有状态改变,赶紧给我刷新界面!而Flutter框架收到通知后,会执行Widget#build,根据新状态重建界面。

状态的更改一定要配合使用setState。通过该方法调用,Flutter会在底层标记Widget的状态,随后触发重建。示例即使修改_counter,若不调用setState,Flutter框架也不会感知到状态变化,因此界面也不会有任何改变。

图计数器示例的代码流程示意图,把这实例的整个代码流程串起:

图3:代码流程示意图

MyApp为Flutter应用的运行实例,在main函数中调用runApp函数实现程序的入口。

应用首页则为MyHomePage,一个拥有_MyHomePageState状态的StatefulWidget。_MyHomePageState通过调用build方法以相应数据配置完成包括导航栏、文本及按钮的页面视图的创建。

而当按钮被点击之后,其关联的控件函数_incrementCounter会触发调用。在这个函数中,通过调用setState更新_counter属性同时,也通知Flutter框架其状态发生变化。随后,Flutter重新调用build方法以新数据配置重建_MyHomePageState的UI,最终完成页面重新渲染。

Widget只是视图的“配置信息”,是数据的映射,“只读”。对StatefulWidget,当数据改变时,需重建Widget去更新界面,即Widget创建销毁会很频繁。

为此,Flutter对此机制

5 优化

其框架内部会通过一个中间层收敛上层UI配置对底层真实渲染的改动,从而最大程度降低对真实渲染视图的修改,提高渲染效率,而不是上层UI配置变就要销毁整个渲染视图树重建。

这样Widget仅是一个轻量级的数据配置存储结构,它的重新创建速度非常快,所以我们可放心重建任何需更新的视图,无需分别修改各子Widget特定样式。

6 总结

先通过Flutter标准模板创建了计数器示例,并分析了Flutter的项目结构,以及Flutter工程与原生Android、iOS工程的联系,知道了Flutter代码是怎么运行在原生系统上的。

然后,学习示例项目代码,了解了Flutter应用结构及页面结构,并认识了构建Flutter的基础,也就是Widget,以及状态管理机制,知道了Flutter页面是如何构建的,StatelessWidget与StatefulWidget的区别,以及如何通过State的成员函数setState以数据驱动的方式更新状态,从而更新页面。

有原生Android和iOS框架开发经验的同学,可能更习惯命令式UI编程风格:手动创建UI组件,在需要更改UI时调用其方法修改视觉属性。而Flutter采用声明式UI设计,只需描述当前UI状态(即State),不同UI状态的视觉变更由Flutter在底层完成。

虽然命令式的UI编程风格更直观,但声明式UI编程方式好处是,可以让我们把复杂的视图操作细节交给框架去完成,这样一来不仅可以提高我们的效率,也可专注整个应用和页面的结构和功能。

7 FAQ

示例项目代码在_MyHomePageState类中,直接在build函数里以内联的方式完成了Scaffold页面元素的构建,这样做的好处是什么呢?在实现同样功能的情况下,如果将Scaffold页面元素的构建封装成一个新Widget类,我们该如何处理?

将Scaffold页面元素的构建封装成一个新Widget类的好处是可以提高代码的可复用性和可维护性。这样可以将Scaffold的构建逻辑封装到一个独立的组件中,方便在其他地方重复使用,也方便后续进行修改和维护。

如果要将Scaffold页面元素的构建封装成一个新Widget类,可以创建一个新的StatelessWidget或StatefulWidget类,然后在该类的build方法中返回Scaffold组件的代码。这样就可以在其他地方使用该组件来构建Scaffold页面元素。例如:

class MyScaffold extends StatelessWidget {final Widget body;const MyScaffold({Key? key, required this.body}) : super(key: key);Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('My App'),),body: body,);}
}

然后在其他地方可以通过MyScaffold来构建页面元素,例如:

class MyApp extends StatelessWidget {Widget build(BuildContext context) {return MyScaffold(body: Center(child: Text('Hello, World!'),),);}
}

http://www.ppmy.cn/news/520315.html

相关文章

java idea使用小辣椒的步骤

1.首先从官网了解小辣椒&#xff0c;并下载jar包 https://projectlombok.org/download 2.创建lib文件夹&#xff0c;把jar包放进去 3.将jar包添加到工程中 4.下载lombok插件 5.打开注释处理器 6.可以使用啦

lombok小辣椒的使用

lombok介绍 ​ lombok是一个可以通过简单的注解的形式来帮助我们简化消除一些必须有但显得很臃肿的 Java 代码的工具&#xff0c;简单来说&#xff0c;比如我们新建了一个类&#xff0c;然后在其中写了几个字段&#xff0c;然后通常情况下我们需要手动去建立getter和setter方法…

“小辣椒”,Lombok

注&#xff1a;该文是本博主记录学习之用&#xff0c;没有太多详细的讲解&#xff0c;敬请谅解&#xff01; 在Java项目里&#xff0c;每个JaveBean中我们都需要创建get/set方法&#xff0c;虽然idea中提供了快速构建get/set方法&#xff0c;但是每次增删改属性都需要维护它的…

eclipse安装lombok插件(小辣椒)

1、下载lombok.jar&#xff0c;lombok.jar官方下载地址&#xff1a;https://projectlombok.org/download 2、双击下载好的lombak.jar&#xff0c;安装步骤如下&#xff1a; 2-1.关闭弹出的警告窗口&#xff0c;点击 Specify location… 2-2.选择eclipse的安装目录 2-3.点击…

Lombok小辣椒的安装以及使用

说在前面&#xff1a; lombokk使得javabean变得方便&#xff0c;添加注解的方式就可以实现自动配置全参构造&#xff0c;无参构造&#xff0c;tostring方法&#xff0c;还有get和set方法。以及链式表达式。 以往的javaBean配置连点鼠标四下&#xff0c;当开发的表变多的时候配置…

如何安装lombok(小辣椒)

方法1: 第一步添加如下依赖 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>依赖添加成功后找到下载的lombok-xxx.jar依赖所在的位置 右键找到Copy Qualified Name复制它的全限定名 使用…

SpringBoot 整合小辣椒 Lombok

一、下载 lombok.jar 文件 下载lombok.jar 二、运行下载的lombok.jar文件 打开cmd,使用java -jar (lombok.jar文件的目录) 三、打开安装窗口后,选择自己的 Eclipse 或者 STS 所在的根目录安装 四、添加依赖 <dependency><groupId>org.projectlombok</groupId…

IDEA中使用Lombok(小辣椒)

IDEA中使用Lombok目录 第一步&#xff0c;安装Lombok插件第二步&#xff0c;导入依赖第三步&#xff0c;使用方式常用注解使用实例&#xff1a; 第一步&#xff0c;安装Lombok插件 工作栏找到File>settings>Plugins 找到如图所示插件&#xff0c;并下载,之后按照提示重…