Flutter一共有427个组件,下面我们对于常用的组件进行简单的介绍,便于以后的使用。
1、MaterialApp
MaterialApp 包含了许多的 Widget ,设置main必要的组件,包含路由、脚手架、主页等等。
字段 属性 描述
名称 | 属性 | 描述 |
---|---|---|
navigatorKey |
GlobalKey | 导航键 |
scaffoldMessengerKey |
GlobalKey | 脚手架键 |
home |
Widget | 主页,应用打开时显示的页面 |
routes |
Map<String, WidgetBuilder> | 应用程序顶级路由表 |
initialRoute |
String | 如果构建了导航器,则会显示第一个路由的名称 |
onGenerateRoute |
RouteFactory | 路由管理拦截器 |
onGenerateInitialRoutes |
InitialRouteListFactory | 生成初始化路由 |
onUnknownRoute | RouteFactory | 当onGenerateRoute无法生成路由时调用 |
navigatorObservers | List | 创建导航器的观察者列表 |
builder |
TransitionBuilder | 在导航器上面插入小部件 |
title |
String | 程序切换时显示的标题 |
onGenerateTitle | GenerateAppTitle | 程序切换时生成标题字符串 |
color | Color | 程序切换时应用图标背景颜色(仅安卓有效) |
theme | ThemeData | 主题颜色 |
darkTheme | ThemeData | 暗黑模式主题颜色 |
highContrastTheme | ThemeData | 系统请求“高对比度”使用的主题 |
highContrastDarkTheme | ThemeData | 系统请求“高对比度”暗黑模式下使用的主题颜色 |
themeMode | ThemeMode | 使用哪种模式的主题(默认跟随系统) |
locale | Locale | 初始区域设置 |
localizationsDelegates | Iterable<LocalizationsDelegate> | 本地化代理 |
localeListResolutionCallback | LocaleListResolutionCallback | 失败或未提供设备的语言环境 |
localeResolutionCallback | LocaleResolutionCallback | 负责计算语言环境 |
supportedLocales | Iterable | 本地化地区列表 |
debugShowMaterialGrid | bool | 绘制基线网格叠加层(仅debug模式) |
showPerformanceOverlay | bool | 显示性能叠加 |
checkerboardRasterCacheImages | bool | 打开栅格缓存图像的棋盘格。 |
checkerboardOffscreenLayers | bool | 打开渲染到屏幕外位图的层的棋盘格。 |
showSemanticsDebugger | bool | 打开显示可访问性信息的叠加层 |
debugShowCheckedModeBanner | bool | 调试显示检查模式横幅 |
shortcuts | Map<LogicalKeySet, Intent> | 应用程序意图的键盘快捷键的默认映射。 |
actions | Map<Type, Action> | 包含和定义用户操作的映射 |
restorationScopeId | String | 应用程序状态恢复的标识符 |
scrollBehavior | ScrollBehavior | 可滚动小部件的行为方式 |
2、Scaffold
Scaffold
我们通常俗称为脚手架,Scaffold
实现了基本的 Material Design 布局结构。
在每一个页面中基本都需要用到Scaffold ,除非当你的页面不需要导航区,但仍希望您使用 Scaffold 来作为每个页面的顶级组件。
名称 | 属性 | 描述 |
---|---|---|
appBar | PreferredSizeWidget | 显示脚手架的顶部导航区 |
body | Widget 显示脚手架的主要内容 | |
floatingActionButton | Widget | 悬浮按钮,位于右下角 |
floatingActionButtonLocation | FloatingActionButtonLocation | 决定悬浮按钮的位置 |
floatingActionButtonAnimator | FloatingActionButtonAnimator | 决定悬浮按钮的动画 |
persistentFooterButtons | List | 显示在脚手架底部的一组按钮 |
drawer | Widget | 左侧抽屉菜单组件 |
onDrawerChanged | DrawerCallback | 左侧抽屉菜单改变事件回调 |
endDrawer | Widget | 右侧抽屉菜单组件 |
onEndDrawerChanged | DrawerCallback | 右侧抽屉菜单改变事件回调 |
bottomNavigationBar | Widget | 底部导航条 |
bottomSheet | Widget | 持久在body下方,底部控件上方的控件 |
backgroundColor | Color | 脚手架背景颜色 |
resizeToAvoidBottomInset | bool | 防止小组件重复 |
primary | bool | 脚手架是否延伸到顶部 |
drawerDragStartBehavior | DragStartBehavior | 检测手势行为方式,与drawer配合使用 |
extendBody | bool | 是否延伸到底部 |
extendBodyBehindAppBar | bool | 是否延伸到顶部,用于做半透明、毛玻璃效果的主要控制属性 |
drawerScrimColor | Color | 侧边栏弹出时非遮盖层主页面的颜色 |
drawerEdgeDragWidth | double | 侧边栏弹出时非遮罩层的宽度 |
drawerEnableOpenDragGesture | bool | 左侧抽屉是否支持手势滑动 |
endDrawerEnableOpenDragGesture | bool | 右侧抽屉是否支持手势滑动 |
restorationId | String | 状态还原标识符 |
3、AppBar
AppBar是基于Material Design设计风格的应用栏,一般使用在Scaffold内部,作为顶部导航栏。
- 导航栏里面一般由左侧功能键(返回键、菜单键)、标题、右侧功能键组成,而AppBar里面内置封装了这些组件,使用起来非常方便。
- 可以做一些特殊的导航栏,比如可滚动的导航栏
名称 | 属性 | 描述 |
---|---|---|
key | Key | 当组件在组件树中移动时使用Key可以保持组件之前状态 |
leading | Widget | 通常情况下返回一个返回键(IconButton) |
leadingWidth | double | 左侧leading的宽度,默认56 |
automaticallyImplyLeading | bool | 和leading配合使用,如果为true并且leading为空的情况下,会自动配置返回键 |
title | Widget | 导航栏的标题 |
centerTitle | bool | 标题是否居中,不同操作系统默认显示位置不一样 |
actions | List | 一个Widget列表 |
bottom | PreferredSizeWidget | 出现在导航栏底部的控件 |
elevation | double | 控制导航栏下方阴影的大小 |
shadowColor | Color | 控制导航栏下方阴影的颜色 |
shape | ShapeBorder | 导航栏的形状以及阴影 |
backgroundColor | Color | 导航栏的背景颜色 |
foregroundColor | Color | 导航栏中文本和图标的颜色 |
backwardsCompatibility | bool | 与foregroundColor配合使用 |
iconTheme | IconThemeData | 导航栏图标的颜色、透明度、大小的配置 |
actionsIconTheme | IconThemeData | 导航栏右侧图标的颜色、透明度、大小的配置 |
textTheme | TextTheme | 导航栏文本的排版样式 |
primary | bool | 导航栏是否显示在屏幕顶部 |
excludeHeaderSemantics | bool | 标题是否应该用 [Semantics] 包裹,默认false |
titleSpacing | double | title内容的间距 |
toolbarOpacity | double | 导航栏的透明度 |
bottomOpacity | double | 导航栏底部的透明度 |
toolbarHeight | double | 导航栏的高度,默认kToolbarHeight |
toolbarTextStyle | TextStyle | 导航栏图标的颜色 |
titleTextStyle | TextStyle | 导航栏标题的默认颜色 |
flexibleSpace | Widget | 堆叠在工具栏和选项卡栏的后面 |
systemOverlayStyle | SystemUiOverlayStyle | 叠加层的样式 |
brightness | Brightness | 导航栏的亮度,改属性已废弃,用systemOverlayStyle代替 |
4、TabBar
一个显示水平行选项卡的Widget。 通常创建为 AppBar 的 AppBar.bottom 部分并与 TabBarView 结合使用。
当你的app内容类别比较多的时候,我们常常会用到TabBar,例如网易新闻、京东、B站等,所以TabBar是一个使用非常频繁的组件。如下:
名称 | 属性 | 描述 |
---|---|---|
tabs | List | 两个多个的Tab列表 |
controller | TabController | 控制tab的控制器 |
isScrollable | bool | 标签栏是否可以水平滚动 |
indicatorColor | Color | 设置选中Tab指示器的颜色 |
automaticIndicatorColorAdjustment | bool | 是否自动调整indicatorColor |
indicatorWeight | double | 设置选中Tab指示器线条的粗细 |
indicatorPadding | EdgeInsetsGeometry | 设置选中Tab指示器间距,默认值为 EdgeInsets.zero |
indicator | Decoration | 设置选中Tab指示器的外观 |
indicatorSize | TabBarIndicatorSize | 设置选中Tab指示器的大小 |
labelColor | Color | 设置选中Tab文字的颜色 |
labelStyle | TextStyle | 设置选中Tab文字的样式 |
labelPadding | EdgeInsetsGeometry | 设置选中Tab文字的间距 |
unselectedLabelColor | Color | 设置未选中Tab文字的颜色 |
unselectedLabelStyle | TextStyle | 设置未选中Tab文字的样式 |
dragStartBehavior | DragStartBehavior | 处理拖动开始行为的方式 |
overlayColor | MaterialStateProperty | 定义响应焦点、悬停和飞溅颜色 |
mouseCursor | MouseCursor | 鼠标指针进入或悬停在鼠标指针上时的光标 |
enableFeedback | bool | 检测到的手势是否应提供声音和/或触觉反馈 |
onTap | ValueChanged | 单击Tab时的回调 |
physics | ScrollPhysics TabBar | 的滚动视图如何响应用户输入 |
5、Padding、AnimatedPadding
1、在应用程序中有许多widget 时,这个时候画面常常会变得很拥挤,这个时候如果想要在widget之间来保留一些间距,那就用 Padding。
Padding(
padding: EdgeInsets.fromLTRB(10, 20, 30, 40),
child: Container(
width: 100,
height: 100,
color: Colors.red,
),
),
2、Padding
组件的动画版本,在设置的时间内缩放或放大到指定的padding
import 'package:flutter/material.dart';
class AnimatedPaddingExample extends StatefulWidget {
@override
_AnimatedPaddingExampleState createState() => _AnimatedPaddingExampleState();
}
class _AnimatedPaddingExampleState extends State<AnimatedPaddingExample> {
double paddingAllValue = 0.0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("AnimatedPaddingExample"),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Padding: $paddingAllValue'),
AnimatedPadding(
padding: EdgeInsets.all(paddingAllValue),
duration: Duration(milliseconds: 1000),
curve: Curves.easeInOut,
child: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height / 4,
color: Colors.blue,
),
onEnd: () {
print("动画结束时的回调");
},
),
ElevatedButton(
child: Text('改变padding的值'),
onPressed: () {
setState(() {
paddingAllValue = paddingAllValue == 0.0 ? 50.0 : 0.0;
});
}),
],
),
);
}
}
6、Align、AnimatedAlign
Align 一般是用来确定子控件在父布局中的位置,比如居中、左上等多个对齐方式。
AnimatedAlign是Align
组件的动画版本,只要对齐方式发生改变,它就会在给定的持续时间内自动转换子组件的位置。
/// 顶部左侧对齐
static const Alignment topLeft = Alignment(-1.0, -1.0);
/// 顶部中间对齐
static const Alignment topCenter = Alignment(0.0, -1.0);
/// 顶部右侧对齐
static const Alignment topRight = Alignment(1.0, -1.0);
/// 中间左侧对齐
static const Alignment centerLeft = Alignment(-1.0, 0.0);
/// 垂直居中对齐
static const Alignment center = Alignment(0.0, 0.0);
/// 中间右侧对齐
static const Alignment centerRight = Alignment(1.0, 0.0);
/// 底部左侧对齐
static const Alignment bottomLeft = Alignment(-1.0, 1.0);
/// 底部中间对齐
static const Alignment bottomCenter = Alignment(0.0, 1.0);
/// 底部右侧对齐
static const Alignment bottomRight = Alignment(1.0, 1.0);
InkWell(
onTap: () {
print("忘记密码");
},
child: Align(
alignment: Alignment.center,
child: Text(
"忘记密码",
style:
TextStyle(fontSize: 14, color: Colors.black54),
),
),
),
这里还有另外一种写法,是通过Stack、Positioned来设定“忘记密码”的位置,但是这样定位就比较麻烦了。所以Align设置位置的优势就体现出来。
7、富文本TextSpan
Container(
child: RichText(
text: TextSpan(
text: "登录即代表同意",
style: TextStyle(color: Colors.black),
children: [
TextSpan(
recognizer: TapGestureRecognizer()
..onTap = () {
print('点击了隐私政策');
},
text: "《隐私协议》",
style: TextStyle(color: Colors.blue)),
])),
)
8、ConstrainedBox、BoxConstraints、UnconstrainedBox
1、ConstrainedBox主要目的是对其子组件添加额外的约束,有时候子组件需要自动调整宽度和高度,以达到最佳的适配设计,那么这时候使用ConstrainedBox 是最佳的选择。·ConstrainedBox 只有两个属性,constraints 用来对子组件添加额外约束,child 被约束的子组件。
ConstrainedBox(
constraints: BoxConstraints(
maxWidth: 100,
minHeight: 30,
),
child: Container(
color: Colors.orangeAccent,
child: Text("ConstrainedExample"),
),
)
2、BoxConstraints
BoxConstraints
对 RenderBox
布局的不可变布局约束。
名称 | 属性 | 描述 |
---|---|---|
minWidth | double | 最小宽度,默认0.0 |
maxWidth | double | 最大宽度,默认double.infinity |
minHeight | double | 最小高度,默认0.0 |
maxHeight | double | 最大高度,默认double.infinity |
BoxConstraints方法和说明:
-
tight()
容器的宽度和高度取决于传进来的size,设定多大就是多大。 -
tightFor()
宽度和高度是可选参数,在不传入的情况下能大则大,在传入参数时设定多大就是多大。 -
tightForFinite()
宽度和高度默认给最大值,在不传参数的时候能大则大,在传入参数的时候能紧则紧。 -
loose()
最大宽度和最大高度限定于传入的size,未超出能紧则紧
3、UnconstrainedBox
UnconstrainedBox 不会对子组件产生任何限制,允许其子组件按照本身大小绘制,那么在我们的平时开发过程中用到该组件会相对较少,一般用于去除多重限制 的时候会有一些帮助。
比如AppBar 中 actions 属性的按钮大小是固定的,如果想要修改就可以借助 UnconstrainedBox 去除父元素的限制。
AppBar(
title: Text("ConstrainedExample"),
actions: [
UnconstrainedBox(
child: Container(
width: 20,
height: 20,
color: Colors.pink,
child: IconButton(onPressed: () {}, icon: Icon(Icons.alarm), iconSize: 20, padding: EdgeInsets.zero,),
),
),
IconButton(onPressed: () {}, icon: Icon(Icons.add)),
],
)
8、SizeBox、FittedBox
1、SizeBox
是一个指定尺寸的盒子,一般用来限制子控件的大小,能强制子控件具有特定宽度和高度。
名称 | 属性 | 描述 |
---|---|---|
width | double | 盒子的宽度 |
height | double | 盒子的高度 |
child | widget | 组件 |
SizedBox(
width: 200.0,
height: 300.0,
child: Card(child: Text('Hello World!')),
)
2、FittedBox
当子组件的内容超出父组件大小时,FittedBox 组件的作用是对子组件进行缩放和对齐方式的设置。
主要用于调整子组件缩放位置,关于位置的调整总共有7种,分别为fill contain cover fitWidth fitHeight none scaleDown,接下来我们说一下这七个属性分别代表什么效果。
fill
:不等比例缩放,图片填充满整个控件
contain
:等比例缩放,直到图片的高或者宽填充满控件
cover
:等比例缩放,直到图片的宽和高都充满整个控件,图片可以超出控件的范围,但是会导致显示不完整。
9、OverflowBox、SizedOverflowBox
1、OverflowBox
允许子控件超出父控件的边界。这个特性主要可以用来实现文字或者按钮角标的。
名称 | 属性 | 描述 |
---|---|---|
alignment | AlignmentGeometry | 子组件对齐方式 |
minWidth | double | 最小宽度 |
maxWidth | double | 最大宽度 |
minHeight | double | 最小高度 |
maxHeight | double | 最大高度 |
child | widget | 组件 |
import 'package:flutter/material.dart';
class OverflowBoxExample extends StatefulWidget {
@override
_OverflowBoxExampleState createState() => _OverflowBoxExampleState();
}
class _OverflowBoxExampleState extends State<OverflowBoxExample> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("OverflowBoxExample"),
),
body: Container(
color: Colors.pink,
width: 200.0,
height: 200.0,
padding: const EdgeInsets.all(5.0),
child: OverflowBox(
alignment: Alignment.topLeft,
maxWidth: 300.0,
maxHeight: 500.0,
child: Container(
color: Colors.greenAccent,
width: 1000.0,
height: 1000.0,
),
),
),
);
}
}
OverflowBox展示,子视图超出父视图。
2、SizedOverflowBox 也允许子控件超出父控件的边界,但是它与OverflowBox不同的在于还可以对子组件进行尺寸部分的限制。
import 'package:flutter/material.dart';
class OverflowBoxExample extends StatefulWidget {
@override
_OverflowBoxExampleState createState() => _OverflowBoxExampleState();
}
class _OverflowBoxExampleState extends State<OverflowBoxExample> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("OverflowBoxExample"),
),
body: Container(
color: Colors.orangeAccent,
alignment: Alignment.bottomRight,
width: 200.0,
height: 200.0,
// padding: EdgeInsets.all(5.0),
child: SizedOverflowBox(
size: Size(190.0, 200.0),//对尺寸进行限制
child: Container(
color: Colors.blueAccent,
width: 200.0,
height: 100.0,
),
),
)
);
}
}
10、AspectRatio、FractionallySizedBox
1、AspectRatio
AspectRatio主要的作用是调整子组件设定的宽高比,如播放视频时16:9或4:3等。
名称 | 属性 | 描述 |
---|---|---|
aspectRatio | double | 纵横比例 |
child | Widget | 子组件 |
import 'package:flutter/material.dart';
class AspectRatioExample extends StatefulWidget {
@override
_AspectRatioExampleState createState() => _AspectRatioExampleState();
}
class _AspectRatioExampleState extends State<AspectRatioExample> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("AspectRatioExample"),
),
body: Container(
color: Colors.blue,
alignment: Alignment.center,
width: double.infinity,
height: 100.0,
child: AspectRatio(
aspectRatio: 16 / 9,
child: Container(
color: Colors.orangeAccent,
),
),
),
);
}
}
2、FractionallySizedBox
当我们需要一个控件的尺寸是相对尺寸时,比如当前按钮的宽度占父组件的150%,可以使用FractionallySizedBox来实现此效果。
import 'package:flutter/material.dart';
class AspectRatioExample extends StatefulWidget {
@override
_AspectRatioExampleState createState() => _AspectRatioExampleState();
}
class _AspectRatioExampleState extends State<AspectRatioExample> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("AspectRatioExample"),
),
body: Container(
color: Colors.blue,
alignment: Alignment.center,
width: 150,
height: 150.0,
child: FractionallySizedBox(
alignment: Alignment.topLeft,
widthFactor: 1.5,
heightFactor: 0.5,
child: new Container(
color: Colors.red,
),
),
),
);
}
}
子组件红色盒子是父组件蓝色盒子的1.5倍,所以超出.
11、ClipRect、ClipRRect
1、ClipRect 是给子组件裁剪为给定的矩形大小,默认情况下,ClipRect会阻止其子组件在边界之外展示,如果需要对子组件进行大小和位置的限定,那么还可以通过自定义裁剪路径。
比如:我们展示一张图片,用ClipRect进行包裹,当超出的部分将会被裁剪。
ClipRect(
child: Align(
alignment: Alignment.topLeft,
widthFactor: 0.5,
child: Image.network("https://img1.baidu.com/it/u=2324541312,3167046558&fm=253&fmt=auto&app=120&f=JPEG?w=601&h=400"),
),
2、ClipRRect 是使用圆角矩形剪辑其子项的小部件,默认情况下,ClipRRect 使用自己的边界作为剪辑的基本矩形,但可以使用自定义剪辑器自定义剪辑的大小和位置。
名称 | 属性 | 描述 |
---|---|---|
borderRadius | BorderRadius | 裁剪的边框大小 |
clipper | CustomClipper | 自定义裁剪器 |
clipBehavior | Clip | 子组件边缘裁剪的方式,默认Clip.hardEdge |
child | Widget | 子组件 |
class _ClipRectExampleState extends State<ClipRectExample> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("ClipRectExample"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(20)), //切割四边圆角
child: Container(
color: Colors.purple,
width: 300,
height: 300,
)
),
],
),
),
);
12、椭圆裁剪ClipOval、ClipPath
ClipOval 主要是对子组件进行裁剪椭圆等效果,而当我们需要对一些子组件定义一些复杂的图形时,我们就需要用到ClipPath,比如五角星。
import 'package:flutter/material.dart';
class ClipOvalExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("ClipRectExample"),
),
backgroundColor: Colors.red.shade100,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipOval(
/// 自定义裁剪路径
// clipper: ClipperPath(),
child: Image.network("https://img1.baidu.com/it/u=2324541312,3167046558&fm=253&fmt=auto&app=120&f=JPEG?w=601&h=400"),
),
],
),
),
);
}
}