Flutter 是什么?
我们先来搬运官网的一段介绍,让大家有一个直观的认识:
Flutter是谷歌的移动UI框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织使用,并且Flutter是完全免费、开源的。
简而言之
- 跨端(移动、Web、桌⾯、嵌⼊式)
- ⾼性能(Dart)
- ⾼效开发(热重载)
- 富有表现⼒的 UI(Widget)
温馨提示
- 搭建开发环境
- Dart简介
- ......
这些我们都不讲,今天我们聊一下 Flutter Widget 。让我们开始吧~
Widget 简介
概念
Widget 描述了在当前的配置和状态下,视图所应该 呈现的样⼦。当 Widget 的状态改变时,它会重新构 建其描述(展示的 UI),框架则会对⽐前后变化的 不同,以确定底层渲染树从⼀个状态转换到下⼀个状 态所需的最⼩更改。
Widget目录
描述元素的配置
示例-1
示例-2
Widget 结构
Widget 组合的结构是树,所以叫Widget 树。树中包含
根Widget
- WidgetsApp【自定义风格】
- MaterialApp【基于 WidgetsApp的Material Design 风格
(常用)
】
- CupertinoApp【基于 WidgetsApp 实现的 iOS 风格】
父Widget
子Widget
// main.dart import 'package:flutter/material.dart'; //风格需要先导入哦~ import 'my_home_page_widget.dart'; void main() => runApp(MyApp()); //Flutter会默认把 根Widget 充满屏幕 class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData.light(), home: MyHomePage(title: 'Vava熊の日记'), ); } }
Widget 与 Element
- Widget树实际上是一个配置树,而真正的UI渲染树是由Element构成。
- 一个Widget对象可以对应多个Element对象。根据同一份配置(Widget),可以创建多个实例(Element)。
graph LR Widget配置--> Element1 Widget配置--> Element2 Widget配置--> Element3 Widget配置--> ...
Widget 状态分类
因为渲染是很耗性能的,为了提高 Flutter 的帧率,就要尽量减少不必要的 UI 渲染,所以 Flutter 根据 UI 是否有变化,将 Widget 分为StatelessWidget
&& StatefulWidget
。
StatelessWidget
和StatefulWidget
都是直接继承自Widget类,它们引入了两种Widget模型,接下来我们将重点介绍一下这两个类。
StatelessWidget:immutable(状态不可变)
StatelessWidget是不可变状态的 Widget 抽象类, 只能在加载/构建 Widget 时才绘制一次,无法基于任何事件或用户操作重绘。所以 StatelessWidget生命周期就只有一个
,即 build
函数。
StatelessWidget の Demo
// main.dart import 'package:flutter/material.dart'; import 'stateless.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData.light(), home: MyStatelessApp("123 木头人,不许动 ——from Vava熊") ); } }
//stateless.dart import 'package:flutter/material.dart'; class MyStatelessApp extends StatelessWidget { final String content; MyStatelessApp(this.content); @override Widget build(BuildContext context) { return Scaffold( appBar:AppBar( title: Text('StatelessWidget'), ), body:Center( child: Text(content), ) ); } }