Flutter常用的组件
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代替 |
image.png
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"),
),
)
image.png
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展示,子视图超出父视图。
image.png
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"),
),
],
),
),
);
}
}