在 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
方法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
重启应用,应用像之前一样运行,每次热重载或保存应用程序时都会显示一个单词对