[https://book.flutterchina.club/preface.html](https://book.flutterchina.club/preface.html)
## Scaffold
~~~plain
const Scaffold({
Key key,
this.appBar, // 应用栏,显示在顶部,包括其中的搜索框
this.body, // 页面的主题显示内容
this.floatingActionButton, // 设置显示在上层区域的按钮,默认位置位于右下角
this.floatingActionButtonLocation, // 设置floatingActionButton的位置
this.floatingActionButtonAnimator, // floatingActionButton动画
this.persistentFooterButtons, // 在底部导航栏之上的一组操作按钮
this.drawer, // 左侧导航栏
this.endDrawer, // 右侧导航栏
this.bottomNavigationBar, // 底部导航栏
this.bottomSheet, // 底部可隐藏导航栏
this.backgroundColor, // 内容区域颜色
this.resizeToAvoidBottomInset, //键盘弹出时是否重新绘制,以避免输入框被遮挡
this.primary = true, // 是否计算手机顶部状态栏的高度
this.drawerDragStartBehavior = DragStartBehavior.start, // 拖动的处理
this.extendBody = false, // 是否延伸body至底部
this.extendBodyBehindAppBar = false, // 是否延伸body至顶部
this.drawerScrimColor, // 抽屉遮罩层背景色
this.drawerEdgeDragWidth, // 滑动拉出抽屉的生效距离
this.drawerEnableOpenDragGesture = true, // 确定是否可以通过拖动手势打开Scaffold.drawer, 默认情况下,拖动手势处于启用状态
this.endDrawerEnableOpenDragGesture = true, // 确定是否可以使用拖动手势打开Scaffold.endDrawer,默认情况下,拖动手势处于启用状态。
})
~~~
### BottomNavigationBar
~~~plain
BottomNavigationBar({
Key key,
@required this.items, // 数组,对应于BottomNavigationBarItem这个组件为菜单栏的每一项,其中包含四个属性icon、title、activeIcon和backgroundColor
this.onTap, // 点击触发逻辑,一般用来触发页面的跳转更新
this.currentIndex = 0, // 当前所在的 items 数组中的位置
this.elevation = 8.0, // 设置阴影效果值
BottomNavigationBarType type, // fixed(固定位置)和shifting(浮动效果)
Color fixedColor, // 代表选中时候的颜色,不能和selectedItemColor一起使用
this.backgroundColor, // 背景颜色
this.iconSize = 24.0, // icon 大小
Color selectedItemColor, // 代表选中的颜色,不能和selectedItemColor一起使用
this.unselectedItemColor, // 未选中时颜色
this.selectedIconTheme = const IconThemeData(), // 当前选中的BottomNavigationBarItem.icon中图标的大小,不透明度和颜色
this.unselectedIconTheme = const IconThemeData(), // 当前未选中的BottomNavigationBarItem.icon中图标的大小,不透明度和颜色
this.selectedFontSize = 14.0, // 选中的字体大小
this.unselectedFontSize = 12.0, // 未选中字体大小
this.selectedLabelStyle, // 选中字体样式
this.unselectedLabelStyle, // 未选中字体样式
this.showSelectedLabels = true, // 是否开启选中的样式
bool showUnselectedLabels, // 是否开启未选中的样式
})
~~~
## AppBar
![](https://img.kancloud.cn/b9/ed/b9ed2f19ac2a9d80f2824119e8e5beba_917x876.png)
~~~dart
return MaterialApp(
home: Scaffold(
appBar: AppBar(
//导航条左边的组件
// leading: Icon(Icons.backspace_outlined),
// 这个会把 左侧的图标 设置为黑色
// iconTheme: IconThemeData.fallback(),
// 配合leading使用,false则左侧的图标不显示
automaticallyImplyLeading: false,
//标题
title: Text("AppBar学习"),
//做折叠效果使用
// flexibleSpace: FlexibleSpaceBar(),
//导航条右边的一组组件
actions: [
Icon(Icons.settings),
Icon(Icons.search),
Icon(Icons.add_circle)
],
//阴影
elevation: 10,
//阴影颜色
shadowColor: Colors.yellow,
//边框样式
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10))),
//背景色
backgroundColor: Colors.red,
//设置状态栏模式
brightness: Brightness.dark,
//设置图标的样式(颜色,不透明度和大小)
iconTheme: IconThemeData(color: Colors.yellow),
//设置actions图标的样式(颜色,不透明度和大小)
actionsIconTheme: IconThemeData(color: Colors.purple),
//设置文字的样式
textTheme: TextTheme(),
//是否沉浸在状态栏下,false会沉浸在状态栏下
primary: true,
//标题是否会显示在中间
centerTitle: true,
//标题左右两边的间距,默认为NavigationToolbar.kMiddleSpacing
titleSpacing: NavigationToolbar.kMiddleSpacing,
//工具栏透明度,值为1.0完全不透明,值为0.0完全透明
toolbarOpacity: 1.0,
//bottom透明度,值为1.0完全不透明,值为0.0完全透明
bottomOpacity: 1.0,
//工具栏高度
toolbarHeight:40,
),
body: Container()),
);
~~~
~~~plain
// 去掉 leading, 也就是头部首位默认的箭头
automaticallyImplyLeading: false,
// 设置高度为0 去掉底部阴影
elevation: 0,
// title 组件俩边的边距为0,以去掉其padding
titleSpacing: 0,
~~~
### DefaultTabController
实战中,如果需要 TabBar 和 TabBarView 联动,通常会创建一个 DefaultTabController 作为它们共同的父级组件
~~~dart
// tabs.length = TabBar 组件的tabs的长度 = TabBarView 的组件数量
length: tabs.length,
// 默认选中 index 为 1的选项卡
initialIndex: 1,
~~~
## TabBar
![](https://img.kancloud.cn/6f/7b/6f7b9da37e5a661b17c9ac63a9b1211d_888x689.png)
~~~dart
return MaterialApp(
home: DefaultTabController(
length: 9,
initialIndex: 0,
child: Scaffold(
appBar: AppBar(
title: Text("AppBar学习"),
bottom: TabBar(
//tab组件集合
tabs: [
Tab(text: "1111"),
Tab(text: "2222"),
Tab(text: "3333"),
Tab(text: "4444"),
Tab(text: "5555"),
Tab(text: "6666"),
Tab(text: "7777"),
Tab(text: "8888"),
Tab(text: "9999"),
],
//tab是否可滚动
isScrollable: true,
//指示器颜色
indicatorColor: Colors.red,
//指示器高度
indicatorWeight: 4,
//指示器内边距
indicatorPadding: EdgeInsets.all(10),
//指示器样式
indicator: BoxDecoration(
color: Colors.purple,
borderRadius: BorderRadius.all(Radius.circular(20))),
//指示器宽度
indicatorSize: TabBarIndicatorSize.tab,
//文本颜色
labelColor: Colors.amberAccent,
//文本样式
labelStyle: TextStyle(fontSize: 15),
//文本内边距
labelPadding:
EdgeInsets.only(left: 10, top: 0, right: 10, bottom: 0),
//未选中文本的颜色
unselectedLabelColor: Colors.orange,
//未选中文本的样式
unselectedLabelStyle: TextStyle(fontSize: 10),
//回调监听
onTap: (index) {
print(index);
},
),
),
body: Container()),
));
~~~
## TabBarView
~~~dart
// 禁止滑动
physics: const NeverScrollableScrollPhysics(),
// 拉倒最边上也可以再拉一拉的效果,实现iOS下弹性效果。
physics: const BouncingScrollPhysics(),
~~~
## Container
~~~dart
Container({
this.alignment,
this.padding, //容器内补白,属于decoration的装饰范围
Color color, // 背景色
Decoration decoration, // 背景装饰
Decoration foregroundDecoration, //前景装饰
double width,//容器的宽度
double height, //容器的高度
BoxConstraints constraints, //容器大小的限制条件
this.margin,//容器外补白,不属于decoration的装饰范围
this.transform, //变换
this.child,
...
})
~~~
decoration可以设置边框、背景色、背景图片、圆角等属性,非常实用。
**注意**: deoration 和 color: 不能同时设置,但是可以把color 设置到 deoration中
同时设置会报错:
![](https://img.kancloud.cn/83/5f/835fec8835e603f70b59079272acf1de_490x350.png)
~~~dart
decoration: new BoxDecoration(
border: new Border.all(width: 2.0, color: Colors.red),
color: Colors.grey,
borderRadius: new BorderRadius.all(new Radius.circular(5.0)),
image: new DecorationImage(
image: new NetworkImage(src),
centerSlice: new Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0),
),
),
~~~
## Dialog 对话框
### AlertDialog
~~~dart
const AlertDialog({
Key? key,
this.title, //对话框标题组件
this.titlePadding, // 标题填充
this.titleTextStyle, //标题文本样式
this.content, // 对话框内容组件
this.contentPadding = const EdgeInsets.fromLTRB(24.0, 20.0, 24.0, 24.0), //内容的填充
this.contentTextStyle,// 内容文本样式
this.actions, // 对话框操作按钮组
this.backgroundColor, // 对话框背景色
this.elevation,// 对话框的阴影
this.semanticLabel, //对话框语义化标签(用于读屏软件)
this.shape, // 对话框外形
})
~~~
![](https://img.kancloud.cn/98/a2/98a21b66408d7eda38906d01685266ca_320x569.png)
~~~dart
AlertDialog(
title: Text("提示"),
content: Text("您确定要删除当前文件吗?"),
actions: <Widget>[
TextButton(
child: Text("取消"),
onPressed: () => Navigator.of(context).pop(), //关闭对话框
),
TextButton(
child: Text("删除"),
onPressed: () {
// ... 执行删除操作
Navigator.of(context).pop(true); //关闭对话框
},
),
],
);
~~~
### SimpleDialog
![](https://img.kancloud.cn/2c/f0/2cf08c64809c2e692ebe4fc17f8e3511_320x569.png)
~~~dart
Future<void> changeLanguage() async {
int? i = await showDialog<int>(
context: context,
builder: (BuildContext context) {
return SimpleDialog(
title: const Text('请选择语言'),
children: <Widget>[
SimpleDialogOption(
onPressed: () {
// 返回1
Navigator.pop(context, 1);
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 6),
child: const Text('中文简体'),
),
),
SimpleDialogOption(
onPressed: () {
// 返回2
Navigator.pop(context, 2);
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 6),
child: const Text('美国英语'),
),
),
],
);
});
if (i != null) {
print("选择了:${i == 1 ? "中文简体" : "美国英语"}");
}
}
~~~
## ListView
~~~dart
ListView({
Axis scrollDirection = Axis.vertical,
ScrollController controller,
ScrollPhysics physics,
bool shrinkWrap = false,
EdgeInsetsGeometry padding,
this.itemExtent,
double cacheExtent,
List<Widget> children = const <Widget>[],
})
~~~
* **scrollDirection**: 列表的滚动方向,可选值有Axis的horizontal和vertical,可以看到默认是垂直方向上滚动;
* **controller** : 控制器,与列表滚动相关,比如监听列表的滚动事件;
* **physics**: 列表滚动至边缘后继续拖动的物理效果,Android与iOS效果不同。Android会呈现出一个波纹状(对应ClampingScrollPhysics),而iOS上有一个回弹的弹性效果(对应BouncingScrollPhysics)。如果你想不同的平台上呈现各自的效果可以使用AlwaysScrollableScrollPhysics,它会根据不同平台自动选用各自的物理效果。如果你想禁用在边缘的拖动效果,那可以使用NeverScrollableScrollPhysics;
* **shrinkWrap**: 该属性将决定列表的长度是否仅包裹其内容的长度。当ListView嵌在一个无限长的容器组件中时,shrinkWrap必须为true,否则Flutter会给出警告;
* **padding**: 列表内边距;
* **itemExtent**: 子元素长度。当列表中的每一项长度是固定的情况下可以指定该值,有助于提高列表的性能(因为它可以帮助ListView在未实际渲染子元素之前就计算出每一项元素的位置);
* **cacheExtent**: 预渲染区域长度,ListView会在其可视区域的两边留一个-cacheExtent长度的区域作为预渲染区域(对于ListView.build或ListView.separated构造函数创建的列表,不在可视区域和预渲染区域内的子元素不会被创建或会被销毁);
* **children**: 容纳子元素的组件数组。
## InkWell
给容器嵌套一些事件, 比如页面有个搜索框,当单击搜索框,弹出搜索页面,这个时候,搜索框其实只是为了弹出搜索页面。就可以把搜索框禁用掉,然后在其外层嵌套 InkWell ,在InkWell 单击事件中打开搜索页面。
~~~dart
const InkWell({
Key key,
Widget child, //子组件
GestureTapCallback onTap, //单击事件
GestureTapCallback onDoubleTap, //双击事件
GestureLongPressCallback onLongPress, //长按事件
GestureTapDownCallback onTapDown, //手指按下
GestureTapCancelCallback onTapCancel, //取消点击事件
ValueChanged<bool> onHighlightChanged, //突出显示或停止突出显示时调用
ValueChanged<bool> onHover, //当指针进入或退出墨水响应区域时调用
MouseCursor mouseCursor,
Color focusColor, //获取焦点颜色
Color hoverColor, //指针悬停时颜色
Color highlightColor, //按住不放时的颜色
MaterialStateProperty<Color> overlayColor,
Color splashColor, //溅墨颜色
InteractiveInkFeatureFactory splashFactory, //自定义溅墨效果
double radius, //溅墨半径
BorderRadius borderRadius, //溅墨元素边框圆角半径
ShapeBorder customBorder, //覆盖borderRadius的自定义剪辑边框
bool enableFeedback = true, //检测到的手势是否应该提供声音和/或触觉反馈,默认true
bool excludeFromSemantics = false, //是否将此小部件引入的手势从语义树中排除。默认false
FocusNode focusNode,
bool canRequestFocus = true,
ValueChanged<bool> onFocusChange,
~~~
## TextField
[https://www.jianshu.com/p/2e28d03d9c03](https://www.jianshu.com/p/2e28d03d9c03)
[https://book.flutterchina.club/chapter3/input\_and\_form.html](https://book.flutterchina.club/chapter3/input_and_form.html)
[
](https://www.jianshu.com/p/2e28d03d9c03)
~~~dart
const TextField({
Key key,
this.controller, //编辑框的控制器,跟文本框的交互一般都通过该属性完成,如果不创建的话默认会自动创建
this.focusNode, //用于管理焦点
this.decoration = const InputDecoration(), //输入框的装饰器,用来修改外观
TextInputType keyboardType, //设置输入类型,不同的输入类型键盘不一样
this.textInputAction, //用于控制键盘动作(一般位于右下角,默认是完成)
this.textCapitalization = TextCapitalization.none,
this.style, //输入的文本样式
this.textAlign = TextAlign.start, //输入的文本位置
this.textDirection, //输入的文字排列方向,一般不会修改这个属性
this.autofocus = false, //是否自动获取焦点
this.obscureText = false, //是否隐藏输入的文字,一般用在密码输入框中
this.autocorrect = true, //是否自动校验
this.maxLines = 1, //最大行
this.maxLength, //能输入的最大字符个数
this.maxLengthEnforced = true, //配合maxLength一起使用,在达到最大长度时是否阻止输入
this.onChanged, //输入文本发生变化时的回调
this.onEditingComplete, //点击键盘完成按钮时触发的回调,该回调没有参数,(){}
this.onSubmitted, //同样是点击键盘完成按钮时触发的回调,该回调有参数,参数即为当前输入框中的值。(String){}
this.inputFormatters, //对输入文本的校验
this.enabled, //输入框是否可用
this.cursorWidth = 2.0, //光标的宽度
this.cursorRadius, //光标的圆角
this.cursorColor, //光标的颜色
this.keyboardAppearance,
this.scrollPadding = const EdgeInsets.all(20.0),
this.dragStartBehavior = DragStartBehavior.down,
this.enableInteractiveSelection,
this.onTap, //点击输入框时的回调(){}
this.buildCounter,
})
~~~
### InputDecoration
~~~dart
InputDecoration({
this.icon, //位于装饰器外部和输入框前面的图片
this.labelText, //用于描述输入框,例如这个输入框是用来输入用户名还是密码的,当输入框获取焦点时默认会浮动到上方,
this.labelStyle, // 控制labelText的样式,接收一个TextStyle类型的值
this.helperText, //辅助文本,位于输入框下方,如果errorText不为空的话,则helperText不会显示
this.helperStyle, //helperText的样式
this.hintText, //提示文本,位于输入框内部
this.hintStyle, //hintText的样式
this.hintMaxLines, //提示信息最大行数
this.errorText, //错误信息提示
this.errorStyle, //errorText的样式
this.errorMaxLines, //errorText最大行数
this.hasFloatingPlaceholder = true, //labelText是否浮动,默认为true,修改为false则labelText在输入框获取焦点时不会浮动且不显示
this.isDense, //改变输入框是否为密集型,默认为false,修改为true时,图标及间距会变小
this.contentPadding, //内间距
this.prefixIcon, //位于输入框内部起始位置的图标。
this.prefix, //预先填充的Widget,跟prefixText同时只能出现一个
this.prefixText, //预填充的文本,例如手机号前面预先加上区号等
this.prefixStyle, //prefixText的样式
this.suffixIcon, //位于输入框后面的图片,例如一般输入框后面会有个眼睛,控制输入内容是否明文
this.suffix, //位于输入框尾部的控件,同样的不能和suffixText同时使用
this.suffixText,//位于尾部的填充文字
this.suffixStyle, //suffixText的样式
this.counter,//位于输入框右下方的小控件,不能和counterText同时使用
this.counterText,//位于右下方显示的文本,常用于显示输入的字符数量
this.counterStyle, //counterText的样式
this.filled, //如果为true,则输入使用fillColor指定的颜色填充
this.fillColor, //相当于输入框的背景颜色
this.errorBorder, //errorText不为空,输入框没有焦点时要显示的边框
this.focusedBorder, //输入框有焦点时的边框,如果errorText不为空的话,该属性无效
this.focusedErrorBorder, //errorText不为空时,输入框有焦点时的边框
this.disabledBorder, //输入框禁用时显示的边框,如果errorText不为空的话,该属性无效
this.enabledBorder, //输入框可用时显示的边框,如果errorText不为空的话,该属性无效
this.border, //正常情况下的border
this.enabled = true, //输入框是否可用
this.semanticCounterText,
this.alignLabelWithHint,
})
~~~
[https://www.jianshu.com/p/5760eb783e3e](https://www.jianshu.com/p/5760eb783e3e)
[https://blog.csdn.net/shulianghan/article/details/115341908](https://blog.csdn.net/shulianghan/article/details/115341908)
[https://blog.csdn.net/yuzhiqiang\_1993/article/details/88204031](https://blog.csdn.net/yuzhiqiang_1993/article/details/88204031)