一.Flutter 简单介绍
与 Linux 或 Windows 操作系统一样,移动操作系统或移动操作系统是一种软件平台,可帮助其他程序在移动设备上运行。该平台专为在移动电话、智能手机、PDA、平板电脑和其他手持设备等设备上运行而设计。
开发移动应用程序是一项复杂且具有挑战性的任务。有各种操作系统,每个操作系统都有一个框架来开发移动应用程序。以Android为例,原生框架基于Java语言,而iOS则基于Objective-C/Swift语言。开发支持 Android 和 Apple 操作系统的应用程序,需要在不同框架中使用两种语言进行编码。 Flutter可以帮助减少工作量并克服这种复杂性。
Flutter 是一个开源框架,用于跨操作系统创建高质量、高性能的移动应用程序。它是一个便携式用户界面 (UI) 框架,用于为移动、Web 和桌面构建现代本机和反应式应用程序。
Flutter 的框架基于 Dart 语言。它通过直接在操作系统的画布中而不是通过本机框架渲染 UI 来实现高性能。尽管 Flutter 用于为高性能和出色的移动应用程序创建漂亮且可自定义的小部件,但它也有其优点和缺点。
1.优点
1).Dart 有一个大型的软件包存储库,允许您扩展应用程序的功能。
2).开发人员只需为两个应用程序(Android 和 iOS)编写一个代码库。 Flutter 将来甚至可能会扩展到另一个平台。
3).Flutter 需要较少的测试。 鉴于其单一的代码库,我们只需要为两个平台编写一次自动化测试。
4).Flutter 的简单性以及自定义和扩展能力使其成为加快开发速度的强大工具。使用 Flutter,开发人员可以完全控制小部件及其布局。
5).Flutter 提供了很棒的开发人员工具,具有惊人的热重载功能。
2.缺点
1).开发人员必须学习 Dart 语言才能为 Flutter 编写代码。
2).现代框架都是尽量将逻辑和 UI 分开; 然而,Flutter 中用户界面和逻辑在 是混合的。
3).Flutter 是另一个创建移动应用程序的框架。 开发人员发现在人口众多的细分市场中选择正确的开发工具具有挑战性。
二.flutter 组件介绍
Flutter 框架基于“一切都是小部件”的核心概念。 小部件只不过是 Flutter 应用程序的构建块。 每个小部件都是 UI 的不可变声明。 小部件是 UI 不同部分的配置或说明,将小部件放在一起即可创建应用程序。所以记住,Flutter 中万物皆为Widget。根据事件的类型,小部件分为无状态(StatelessWidget)和有状态(StatefulWidget)。
1.StatelessWidget
StatelessWidget相对比较简单,它继承自widget类,重写了createElement()方法:源码如下:
abstract class StatelessWidget extends Widget {
/// Initializes [key] for subclasses.
const StatelessWidget({ Key? key }) : super(key: key);
@override
StatelessElement createElement() => StatelessElement(this);
@protected
Widget build(BuildContext context);
2.StatefulWidget
StatefulWidget也是继承自widget类,并重写了createElement()方法,不同的是返回的Element 对象并不相同;另外StatefulWidget类中添加了一个新的接口createState()。
abstract class StatefulWidget extends Widget {
/// Initializes [key] for subclasses.
const StatefulWidget({ Key? key }) : super(key: key);
@override
StatefulElement createElement() => StatefulElement(this);
@protected
@factory
State createState(); // ignore: no_logic_in_create_state, this is the original sin
}
StatefulWidget 类会对应一个 State 类,State表示与其对应的 StatefulWidget 要维护的状态,State 中的保存的状态信息可以进行如下操作:
1).widget 构建时可以被同步读取。
2).widget 生命周期可以被改变,当State被改变时,可以手动调用其setState()方法通知Flutter 框架状态发生改变,Flutter 框架在收到消息后,会重新调用其build方法重新构建 widget 树,从而达到更新UI的目的。
State 中有两个常用属性:
1).widget,它表示与该 State 实例关联的 widget 实例,由Flutter 框架动态设置。
2).context,StatefulWidget对应的 BuildContext,作用同StatelessWidget 的BuildContext。
State的生命周期图如下:
1).initState,当 widget 第一次插入到 widget 树时会被调用,对于每一个State对象,Flutter 框架只会调用一次该回调,所以,通常在该回调中做一些一次性的操作,如状态初始化、订阅子树的事件通知等。
2).didChangeDependencies(),当State对象的依赖发生变化时会被调用等。
3).build(),它主要是用于构建 widget 子树的,在initState()/didUpdateWidget()/setState()/didChangeDependencies()之后会被调用。
4).didUpdateWidget ():在 widget 重新构建时调用。
5).deactivate():当 State 对象从树中被移除时,会调用此回调。
6).dispose():当 State 对象从树中被永久移除时调用;通常在此回调中释放资源。
三.Flutter Demo展示
1.StatelessWidget简单使用,打印显示'Hello World!'
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Welcome to Flutter',
home: Scaffold(
appBar: AppBar(
title: Text('Welcome to Flutter'),
),
body: Center(
child: Text('Hello World!'),
),
),
);
}
}
2.StatefulWidget,实现简单计算器
import 'package:flutter/material.dart';
class calculatePage extends StatefulWidget {
const calculatePage({Key? key}) : super(key: key);
@override
State createState() => calculatePageState();
}
class calculatePageState extends State<calculatePage> {
var num1 = 0, num2 = 0, sum = 0;
final TextEditingController text1 = TextEditingController(text: "0");
final TextEditingController text2 = TextEditingController(text: "0");
void doAddition() {
setState(() {
print("doAddition---begin");
num1 = int.parse(text1.text);
num2 = int.parse(text2.text);
sum = num1 + num2;
});
}
void doSub() {
setState(() {
print("doSub---begin");
num1 = int.parse(text1.text);
num2 = int.parse(text2.text);
sum = num1 - num2;
});
}
void doMul() {
setState(() {
print("doSub---begin");
num1 = int.parse(text1.text);
num2 = int.parse(text2.text);
sum = num1 * num2;
});
}
void doDiv() {
setState(() {
print("doSub---begin");
num1 = int.parse(text1.text);
num2 = int.parse(text2.text);
sum = num1 ~/ num2;
});
}
void doClear() {
setState(() {
print("doSub---begin");
text1.text = "0";
text2.text = "0";
sum=0;
});
}
@override
Widget build(BuildContext context) {
print("build---begin");
return Scaffold(
appBar: AppBar(
title: const Text("calculatePage"),
),
body: Container(
padding: const EdgeInsets.all(45.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: "Please Enter Number one"),
controller: text1,
),
TextField(
keyboardType: TextInputType.number,
decoration: const InputDecoration(hintText: "Please Enter Number two"),
controller: text2,
),
const Padding(
padding: EdgeInsets.only(top: 18.0),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"Calculate Output : $sum",
style: const TextStyle(
fontSize: 16.0,
fontWeight: FontWeight.bold,
color: Colors.orange),
),
],
),
const Padding(
padding: EdgeInsets.only(top: 18.0),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
MaterialButton(
child: const Text("+"),
color: Colors.greenAccent,
onPressed: doAddition,
),
MaterialButton(
child: const Text("-"),
color: Colors.greenAccent,
onPressed: doSub,
),
],
),
const Padding(
padding: EdgeInsets.only(top: 18.0),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
MaterialButton(
child: const Text("*"),
color: Colors.greenAccent,
onPressed: doMul,
),
MaterialButton(
child: const Text("/"),
color: Colors.greenAccent,
onPressed: doDiv,
),
],
),
const Padding(
padding: EdgeInsets.only(top: 18.0),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
MaterialButton(
child: const Text("Clear"),
color: Colors.red,
onPressed: doClear,
),
],
)
],
),
),
);
}
}