今天实现个登陆页,介绍一些 FLutter 常用到的 Widget,可以说麻雀虽小部件不少。实际效果如下:
项目地址放在文后,看完效果图先罗列使用到以及今天要介绍的 Widget,StatelessWidget、StatefulWidget、MaterialApp、Scaffold、AppBar、SingleChildScrollView、Container、Padding、Column、Image、Text、TextField、RaisedButton,可以把项目跑起来对照下文看,接下来对他们的一些常用或可能用到的一些属性做一个注解。
StatelessWidget
页面一旦生成后,数据状态就不可改变,请使用用 StatelessWidget
StatefulWidget
页面生成后,数据状态就可改变,请使用用 StatefulWidget
MaterialApp
MaterialApp 代表一个使用 Material 风格的应用
const MaterialApp({
Key key,
this.navigatorKey,
this.home, // 进入应用的默认界面
this.routes = const {}, // 应用路由导航数组
this.initialRoute, // 默认初始化的路由
this.onGenerateRoute, // 生成路由时回调
this.onUnknownRoute,
this.navigatorObservers = const [],
this.builder,
this.title = '', // 多任务窗口显示的应用名称
this.onGenerateTitle,
this.color,
this.theme, // 应用 UI 使用的主题风格
this.darkTheme,
this.themeMode = ThemeMode.system,
this.locale, // 带 locale ,均与多语言设置相关
this.localizationsDelegates,
this.localeListResolutionCallback,
this.localeResolutionCallback,
this.supportedLocales = const [Locale('en', 'US')], // 默认支持的语言环境,所以部分系统部件,默认不会显示中文
this.debugShowMaterialGrid = false,
this.showPerformanceOverlay = false,
this.checkerboardRasterCacheImages = false,
this.checkerboardOffscreenLayers = false,
this.showSemanticsDebugger = false,
this.debugShowCheckedModeBanner = true, // 是否显示 DEBUG 标识
})
MaterialApp 主要用于应用整体配置,包含应用主题、路由、多语言以及一些调试开关。从它的默认参数也可看出一个问题,就是默认支持英语语言环境,所以 TextField 长按操作菜单,默认情况仅显示英文。
解决方案:看项目关于语言设置部分。
Scaffold 用来来快速构建一个 Material Design 风格的页面,原本需要我们自己做的事情,系统帮我们做了。
Scaffold({
Key key,
this.appBar, // 显示在顶部的一个部件 AppBar(个人叫做标题栏)
this.body, // 页面主体内容 Widget
this.floatingActionButton, // Material 中定义的悬浮按钮
this.floatingActionButtonLocation, // 控制悬浮按钮位置
this.floatingActionButtonAnimator, // 悬浮按钮动画
this.persistentFooterButtons, // 固定显示在页面下方的按钮,在body和bottomNavigationBar之间
this.drawer, // 页面左侧侧边栏
this.endDrawer, // 页面右侧侧边栏
this.bottomNavigationBar, // 页面底部导航栏
this.bottomSheet, // 显示在页面底部的叠加层
this.backgroundColor, // 页面背景颜色
this.resizeToAvoidBottomPadding, // 页面内容是否重新布局 已过时
this.resizeToAvoidBottomInset, // 页面内容是否重新布局 推荐使用
this.primary = true, // 是否需要显示到屏幕顶部(白话:状态栏是否有个 padding)
this.drawerDragStartBehavior = DragStartBehavior.start,
this.extendBody = false, //是否扩展body,当页面有 bottomNavigationBar 或 persistentFooterButtons时,body 扩展到他们下面,即被他们覆盖
this.drawerScrimColor, //侧边栏
this.drawerEdgeDragWidth,
}
Scaffold 主要用于应用页面配置,相当于系统给我们搭建了个页面框架,在这里我们可以快速的实现标题栏,内容,底部导航栏以及侧边栏等等,当然有一些属性我们还是很少用到,知道并使用默认就好。
AppBar
AppBar 页面顶部导航栏,应用栏,但是我习惯了叫标题栏
AppBar({
Key key,
this.leading, // leading 显示在[标题]之前的部件,比如抽屉菜单、返回按钮
this.automaticallyImplyLeading = true, // 是否自动实现 leading
this.title, // 显示标题
this.actions, // 右侧
this.flexibleSpace, // 堆叠在标题栏后面部件,高度与标题栏高度相同。
this.bottom, // 标题栏底部菜单,通常为Tab按钮组
this.elevation, // 标题栏阴影
this.shape,
this.backgroundColor, //标题栏背景色
this.brightness, // 标题栏亮度,设置为 light 状态栏文字则为黑色
this.iconTheme, // 以下4个各种样式
this.actionsIconTheme,
this.textTheme,
this.primary = true,
this.centerTitle, // 是否居中页面标题
this.titleSpacing = NavigationToolbar.kMiddleSpacing,
this.toolbarOpacity = 1.0, //透明度
this.bottomOpacity = 1.0,
})
SingleChildScrollView
只有一个子 widger 的 ScrollView,当界面内容超过屏幕的时候( 当你在屏幕上看到类似 bottom overflowed by 216 pixels),包裹一个 SingleChildScrollView 是个很好的解决方式。SingleChildScrollView 适用于内容不会超过屏幕太多时,如果超出太多建议适用 ListView 支持复用。
SingleChildScrollView({
Key key,
this.scrollDirection = Axis.vertical, // 滚动放下
this.reverse = false, // 是否反向滚动
this.padding, // 内边距
bool primary,
this.physics, // 如何响应用户输入
this.controller,
this.child,
this.dragStartBehavior = DragStartBehavior.start,
})
Container
Container 可以看成一个容器,方便我们指定宽高、内外边距、背景色等等等
Container({
Key key,
this.alignment, // 对齐方式
this.padding, // 内边距
Color color, // 颜色
Decoration decoration, // 背景装饰器
this.foregroundDecoration, // 前景装饰器
double width, // 宽
double height, // 高
BoxConstraints constraints, // 容器约束
this.margin, // 外边距
this.transform, // 应用于容器的变换矩阵
this.child,
})
Padding
这就没啥了,就是一个 Padding 内边距
Padding({
Key key,
@required this.padding,
Widget child,
})
Column
Column 竖向线性布局,默认将一组 Widget 从上至下摆放,需要注意主轴方向(Widget 摆放方向)和从轴方向(与摆放方向垂直)
Column({
Key key,
MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start, // 主轴对齐方式
MainAxisSize mainAxisSize = MainAxisSize.max, // 主轴每个Item行高
CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center, // 从轴对齐方式
TextDirection textDirection, // 子组件的布局顺序时 从左至右还是从右至左
VerticalDirection verticalDirection = VerticalDirection.down, // 主轴布局方向
TextBaseline textBaseline, // 水平对齐基线
List children = const [],
})
Image
Flutter 中的图片显示部件,可以加载网络、文件、内存以及asset中图片资源,一般使用 Image.asset、Image.network、Image.file、Image.memory 进行加载
Image({
Key key,
@required this.image, // ImageProvider
this.frameBuilder,
this.loadingBuilder,
this.semanticLabel,
this.excludeFromSemantics = false,
this.width, // 图片宽度
this.height, // 图片高度
this.color, // 图片混合色值
this.colorBlendMode, // 图片与颜色混合模式
this.fit, // 图片填充方式
this.alignment = Alignment.center, // 对齐方式
this.repeat = ImageRepeat.noRepeat, // 重复方式
this.centerSlice, //
this.matchTextDirection = false,
this.gaplessPlayback = false,
this.filterQuality = FilterQuality.low, //图片过滤质量
})
Text、RichText
Text(
this.data, {
Key key,
this.style, // 文本样式(颜色、字体、倾斜等)
this.strutStyle,
this.textAlign, // 文本对齐方式
this.textDirection, // 文本方向
this.locale,
this.softWrap, //文本
this.overflow, // 文本溢出(超出指定行数),截断方式
this.textScaleFactor, // 文本缩放比例
this.maxLines, // 文本显示行数
this.semanticsLabel,
this.textWidthBasis, // 文本宽度包含方式; parent:以父部件宽度包含,longestLine:以最长行包含
})
RichText({
Key key,
@required this.text, // 这里是个 InlineSpan 其他属性都和 Text 差不多
this.textAlign = TextAlign.start,
this.textDirection,
this.softWrap = true,
this.overflow = TextOverflow.clip,
this.textScaleFactor = 1.0,
this.maxLines,
this.locale,
this.strutStyle,
this.textWidthBasis = TextWidthBasis.parent,
})
本文Demo里面隐私协议部分即用到了富文本,当然实现富文本部件也可以用 Text.rich 方式。
TextField
Flutter 中文本输入可以使用 TextField 、 TextFromField
TextField({
Key key,
this.controller, // 文本编辑控制器 可以设置监听 设置默认值 取值等
this.focusNode, // 输入框焦点
this.decoration = const InputDecoration(), // 输入框样式
TextInputType keyboardType, // 输入框键盘类型
this.textInputAction, // 文本输入 键盘事件
this.textCapitalization = TextCapitalization.none,
this.style, // 输入文本样式
this.strutStyle,
this.textAlign = TextAlign.start, // 文本对齐方式
this.textAlignVertical, // 竖向对齐方式
this.textDirection, // 文本方向
this.readOnly = false,
ToolbarOptions toolbarOptions,
this.showCursor, // 是否显示光标
this.autofocus = false, // 是否自动获取焦点
this.obscureText = false, // 是否隐藏文本
this.autocorrect = true,
this.maxLines = 1, // 最大行数
this.minLines, // 最小行数
this.expands = false,
this.maxLength, // 最大长度
this.maxLengthEnforced = true, // 是否执行maxLength
this.onChanged, // 内容变化回调
this.onEditingComplete, // 编辑完成回调
this.onSubmitted, // 提交回调
this.inputFormatters, // 输入格式化
this.enabled, // 是否可输入
this.cursorWidth = 2.0, // 光标宽度
this.cursorRadius, // 光标圆角
this.cursorColor, // 光标颜色
this.keyboardAppearance, // 键盘外观 iOS设备有效
this.scrollPadding = const EdgeInsets.all(20.0),
this.dragStartBehavior = DragStartBehavior.start,
this.enableInteractiveSelection = true,
this.onTap, // 点击事件
this.buildCounter,
this.scrollController, // 滚动控制器
this.scrollPhysics,
})
RaisedButton
在 Flutter 中有很多 Button,比如这里的浮动按钮 RaisedButton 和与之对应扁平按钮 FlatButton,还有IconButton、OutlineButton 等,这里说明下浮动按钮属性。
RaisedButton({
Key key,
@required VoidCallback onPressed, // 按下回调
ValueChanged onHighlightChanged,
ButtonTextTheme textTheme, // 按钮文字主题
Color textColor, // 文字颜色
Color disabledTextColor, // 禁用时文字颜色
Color color, // 背景色
Color disabledColor, // 禁用时背景色
Color focusColor,
Color hoverColor,
Color highlightColor, // 按下时背景色
Color splashColor, // 点击时水波纹颜色
Brightness colorBrightness, // 颜色亮度
double elevation, // 阴影
double focusElevation,
double hoverElevation,
double highlightElevation, // 按下时阴影
double disabledElevation, // 禁用时阴影
EdgeInsetsGeometry padding, // 内边距
ShapeBorder shape, // 边框外形
Clip clipBehavior,
FocusNode focusNode,
bool autofocus = false, // 是否自动获取焦点
MaterialTapTargetSize materialTapTargetSize,
Duration animationDuration,
Widget child,
})
介绍了登陆页面用到的 Widget 很多属性,但实际我们可能用不了这么多,了解它的最好的办法就是写个Demo,各个属性都设置取消试试。
如果你看到了这里,觉得文章写得不错就给个赞呗!欢迎大家评论讨论!如果你觉得那里值得改进的,请给我留言。一定会认真查询,修正不足,定期免费分享技术干货。喜欢的小伙伴可以关注一下哦。谢谢!