在 Flutter 中,几乎所有的东西都是 widget,例如:布局模型、图像、图标、文本、排列、限制、对齐、行、列、网格等
Flutter 布局的核心机制就是 widgets,可以通过组合 widgets 来构建更复杂的 widgets 来创建布局
runApp() 函数会持有传入的 Widget,并且使它成为 widget 树中的根节点。在上例中,Widget 树有两个 widgets, Center widget 及其子 widget —— Text widget。框架会强制让根 widget 铺满整个屏幕,也就是说“Hello Flutter”会在屏幕上居中显示
Flutter 从 React 中吸取灵感,通过现代化框架创建出精美的组件。它的核心思想是用 widgets 来构建 UI 界面,widgets 描述了在当前的配置和状态下视图所应该呈现的样子。当 widget 的状态改变时,它会重新构建其描述(展示的UI),框架则会对比前后变化的不同,以确定底层渲染树从一个状态转换到下一个状态所需的最小更改
widget 要点如下:
(1)、widget 是用于构建 UI 的类
(2)、widget 可以用于布局和展示 UI 元素
(3)、通过组合简单的 widgets 来构建复杂的 widgets
在 pubspec.yaml 文件的 flutter 部分加入 uses-material-design: true 就可以使用 Material 的特性。Material Design 是谷歌推出的前端 UI 解决方案,是一种移动端和网页端通用的视觉设计语言
Scaffold 是 Material Design 提供的一个 widget,它提供了默认的导航栏、标题和包含主屏幕 widget 树的body属性
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: 'Welcome to Flutter', home: Scaffold( appBar: AppBar( title: const Text('Flutter Title'), backgroundColor: Colors.purple, leading: const Icon(Icons.menu), actions: const [Icon(Icons.search), Icon(Icons.more)], ), body: const Center( child: Text( 'Hello Flutter', style: TextStyle( fontSize: 50, ), ), ), bottomNavigationBar: BottomNavigationBar( type: BottomNavigationBarType.fixed, backgroundColor: Colors.purple, selectedItemColor: Colors.white, unselectedItemColor: Colors.white.withOpacity(.60), selectedFontSize: 16, unselectedFontSize: 16, items: const [ BottomNavigationBarItem( icon: Icon(Icons.favorite), label: 'Favorities', ), BottomNavigationBarItem( icon: Icon(Icons.music_note), label: 'Music', ), BottomNavigationBarItem( icon: Icon(Icons.location_on), label: 'Places', ), BottomNavigationBarItem( icon: Icon(Icons.library_books), label: 'News', ) ]), ) // home: Home(), ); } }
MaterialApp 部分属性
title(任务管理器中的标题)-- String 类型
home(主内容)-- Widget 组件
debugShowCheckedModeBanner(是否显示左上角调试标记)-- bool 类型,默认值 true
Scaffold 部分属性
appBar(应用头部)-- AppBar 类型
body(应用主体)-- Widget 组件
floatingActionButton(右下角的浮动按钮)-- Widget 组件
drawer(左侧抽屉菜单)-- Widget 组件
endDrawer(右侧抽屉菜单)-- Widget 组件
使用外部 package
方法1:在 pubspec.yaml 配置文件中找到 dependencies 或 dev_dependencies 选项,添加包名并指定版本号
english_words: ^4.0.0
然后,执行 flutter pub get 指令将依赖包按照到项目中。安装成功后可以在 pubspec.lock 文件中,可以查看安装包的名称和版本信息
方法2:直接执行 flutter pub add http 指令
示例中使用安装好的 english_words包,每次单击热重载或保存项目时,都会在正在运行的应用程序中随机选择不同的单词对
import 'package:flutter/material.dart'; import 'package:english_words/english_words.dart'; class Home extends StatelessWidget { const Home({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final wordPair = WordPair.random(); return MaterialApp( title: 'Welcome to Flutter', home: Scaffold( appBar: AppBar( title: const Text('Package Demo'), ), body: Center( child: Text(wordPair.asPascalCase), ))); } }
在写应用的过程中,取决于是否需要管理状态,通常会创建一个新的组件继承 StatelessWidget 或 StatefulWidget。Widget 的主要工作是实现 build() 方法,该方法会实例化和返回一个 widget 并让它显示出来
无状态组件(StatelessWidget)
无状态的 widget 是不可变的,意味着它们的属性不能改变,所有的值都是 final
有状态组件(StatefulWidget)
有状态的 widget 也是不可变的,但其持有的状态可能在 widget 生命周期中发生变化,实现一个有状态的 widget 至少需要两个类:
(1)、一个 StatefulWidget 类
(2)、一个 State 类
import 'package:flutter/material.dart'; import 'package:english_words/english_words.dart'; class Home extends StatelessWidget { const Home({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Welcome to Flutter', home: Scaffold( appBar: AppBar( title: const Text('Package Demo'), ), body: const Center( child: RandomWords(), ))); } } class RandomWords extends StatefulWidget { const RandomWords({Key? key}) : super(key: key); @override State<RandomWords> createState() => _RandomWordsState(); } class _RandomWordsState extends State<RandomWords> { @override Widget build(BuildContext context) { final wordPair = WordPair.random(); return Text(wordPair.asPascalCase); } }
示例说明:
(1)、在 vscode 中输入 sf,编辑器会自动创建一个 Stateful widget 和它自己的状态类
(2)、输入 RandomWords 作为有状态 widget 的名称,其状态类会自动更名为 _RandomWordsState。RandomWords widget 的主要作用就是创建其对应的 State 类,默认情况下,State 类的名称带有下划线前缀用于增强隐私性
(3)、把 RandomWords 内嵌到已有的无状态类 Home widget
重启应用,应用像之前一样运行,每次热重载或保存应用程序时都会显示一个单词对