本文首发于公众号「刘望舒」html
关联系列
ReactNative入门系列
React Native组件
Flutter基础系列前端
学完了Dart语言,接下来就能够学习Widget了,Flutter的UI界面就是由Widget组成的,Widget的数量繁多,所以我会用几篇文章来专门介绍它,本篇就来介绍Basics Widget。java
Flutter的Widget的设计灵感来自于React,主要目的就是使用Widget构建UI。Widget根据其当前配置和状态来描述视图,当Widget的状态发生更改时,Widget会重建其描述。framework将根据前面的描述进行对比,以肯定底层渲染树从一个状态转换到下一个状态所需的最小更改。 在Flutter中,除了Basics 的文本、图片、卡片、输入框这些基础控件,布局方式和动画等也都是由Widget组成的。经过使用不一样类型的Widget,就能够实现复杂的界面。 Widget能够翻译为部件,粗略的至关于Android中的View。Widget和View不一样的是:Widget具备不一样的生命周期:它是不可变的,每当Widget或者其状态发生变化时,Flutter的框架都会建立一个新的Widget实例树。相比之下,Android中的View会被绘制一次,而且在invalidate调用以前不会重绘。程序员
Widget的分类有不少类别,每一个类别下面又包含不少Widget,主要包括如下几种类别:数组
Basics有些特殊,它是由Flutter官方从其余的Widget分类中选取的一些Widget组成的,这些Widget是官方建议开发者构建第一个Flutter应用程序以前,须要知道的,目的是让开发者更快的入门。好比Row属于Layout分类,它就被选进了Basics中。本文遵循了Flutter官方的意图,首先介绍Basics(Basics Widget)。bash
Widget更多的是以组合的形式存在,好比Container是属于Layout中的一个Widget,而Container又由LimitedBox、 ConstrainedBox、Align、 Padding、 DecoratedBox、Transform部件组成。 若是要实现Container的自定义效果,能够组合上面这些Widget以及其余简单的Widget,而不是将Container进行子类化实现。网络
在Android中,咱们能够经过直接更改View来更新视图。可是在Flutter中,Widget是不可变的而且不会直接更新,而是必须使用Widget的状态。 Widget有两种状态分类分别是无状态的StatelessWidget和有状态的StatefulWidget,StatelessWidget是不可变的,设置之后就不可再变化,全部的值都是最终的设置。StatefulWidget能够保存本身的状态,可是Widget是不可变的,所以须要配合State来保存状态。 State拥有本身的声明周期,以下所示:app
名称 | 状态 |
---|---|
initState | create以后被insert到渲染树时调用的,只会调用一次 |
didChangeDependencies | state依赖的对象发生变化时调用 |
didUpdateWidget | Widget状态改变时候调用,可能会调用屡次 |
build | 构建Widget时调用 |
deactivate | 当移除渲染树的时调用 |
dispose | Widget即将销毁时调用 |
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
...
),
),
);
}
}
复制代码
上面的MaterialApp就是一个根Widget,也就是Flutter应用程序的第一个Widget,根Widget有如下几种:框架
若是公司没有特殊要求,这里建议使用MaterialApp作为根Widget就能够了。less
Basics Widget也就是Basics,主要有如下几种:
这里选择一些咱们必需要掌握的Basics Widget来进行讲解。
为了更好的理解这些Basics Widget,咱们须要写一些例子,这些例子须要一个代码模板,方便测试和学习。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(//1
title: 'Welcome to Flutter',
home: Scaffold(//2
appBar: AppBar(//3
title: Text('Basics Widget'),
),
body:
Padding(
padding: EdgeInsets.all(40.0),
child: Text('在这里编写和测试其余Basics Widget'),
),
),
);
}
}
复制代码
上面的代码是稍微改动了官方的Hello World代码,便于测试,具体的代码含义已经在Flutter基础(二)Flutter开发环境搭建和Hello World中讲过了,这里结合本文要讲的内容再说点细节。注释1处的MaterialApp属于Material Components类别中的Widget,MaterialApp中包含了实现Material Design的应用程序所须要的Widget。 注释2和3处的Scaffold和AppBar一样也是Material Components类别中的Widget,Scaffold实现了Material Design布局结构,AppBar是Material Design的应用栏,它们会在下一篇文章介绍Material Components时进行讲解。效果以下图所示:
在4.1小节中已经用了Text,还能够定义样式:
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('Basics Widget'),
),
body: Padding(
padding: EdgeInsets.all(60.0),
child: Text(
'文本样式',
style: TextStyle(
fontSize: 16.0,
color: Colors.indigo,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.bold,
),
),
),
),
);
}
}
复制代码
此次为了便于理解列出了所有的代码,此后的举例只列出改变的部分。 经过TextStyle来定义文本的样式,效果以下:
Image的构造函数有多种:
Image的属性有不少种,主要的属性为fit,用于表示图片的填充模式,参数类型为BoxFit,BoxFit的取值主要有如下几种,示例图片来自flutter官方。
contain 全图显示,保持原比例。
child: Image.network(
"https://upload-images.jianshu.io/upload_images/1417629-53f7d0902457cbe6.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240",
width: 260,
height: 100,
fit: BoxFit.fill,
),
复制代码
效果以下图所示:
凸起按钮RaisedButton是符合Material Design设计规范的按钮,能够经过onPressed来回调按钮的点击。
RaisedButton(
onPressed: () => print("onPressed"),
color: Colors.lightBlueAccent,
child: Text('RaisedButton', style: TextStyle(fontSize: 10)),
),
复制代码
除了使用RaisedButton,flutter还提供了其余的按钮,好比FlatButton、IconButton、FloatingActionButton等等,它们的使用方法和RaisedButton大同小异,这里就再也不赘述。
Basics Widget中的还有Row、Column、Container等Widget,这里简单介绍下。
Row Row用于在水平方向显示数组中的子元素Widget。
child: Row(
children: <Widget>[
Icon(Icons.access_alarm),
Icon(Icons.add_a_photo),
Icon(Icons.add_call),
],
),
复制代码
垂直方向显示数组中的子元素Widget用Column,使用方法和Row同样。这里须要提到的是Expanded,能够用Expanded来配合Row和Column使用,用来填充剩余的空间。
Row(
children: <Widget>[
Icon(Icons.access_alarm),
Icon(Icons.add_a_photo),
Icon(Icons.add_call),
Expanded(
child: FittedBox(
fit: BoxFit.contain,
child: const FlutterLogo(), ), flex: 2, ), Expanded( child: Text( "占剩余部分的三分之一", ), flex: 1, ), ], ), 复制代码
其中的Expanded的做用是在本身的尺寸范围内缩放而且调整child位置,使得child适合其尺寸。FlutterLogo是Basics Widget中的一种,用于展现Flutter图标。使用flex能够调整两个Expanded的占比。
Container 一个便利的容器Widget,能够设置Widget的背景、尺寸、定位。描述起来有些抽象,能够理解它和Android中的ViewGroup差很少。
Container(
decoration:BoxDecoration(
color: Colors.lightGreen
),
child: Text('Container'),
padding: EdgeInsets.all(36.0),
margin: EdgeInsets.all(10.0),
),
复制代码
Container的padding和margin属性和Android中的做用是相似的:
本文主要介绍了什么是Widget、Widget的分类、Basics Widget。由于Widget的数量繁多,官方将Widget进行了分类,并将须要先了解的Widget纳入到了Basics Widget中,后续文章会介绍其余的Widge分类。
分享大前端、Android、Java等技术,助力5万程序员成长进阶。