脚手架(Scaffold)
脚手架Scaffold是Flutter UI中重要的组成部分,实现了大部分的APP页面需求,相当于房屋框体结构,页面一般都需要基于Scaffold来开发,主要成员包含:appBar(顶部Bar)、body(主体)、floatingActionButton(悬浮按钮)、drawer/endDrawer(抽屉)、bottomSheet(底部Sheet)、bottomNavigationBar(底部导航栏)。
appBar
appBar是Scaffold中的顶部工具栏,显示标题和添加一些便捷常用的工具/菜单。appBar接受PreferredSizeWidget,可自定bar,也可使用Flutter提供的AppBar(),AppBar的构成如下图,主要包含leading(导航)、title(标题)、actions(工具/菜单)、flexibleSpace(灵活空间)、bottom(底部扩展) 几个部分。
- leading 导航:非根节点没有重写的话,会自动生成一个返回按钮,并实现关闭当前页面的路由操作。
- title 标题:页面的标题。
- actions 工具/菜单:一个 Widget 列表,作为便捷菜单或工具栏。
- flexibleSpace 灵活空间:一个显示在 AppBar 下方的控件,高度和 AppBar 高度一样。
- bottom 底部拓展:通常用来实现TabBar。
body
body是Scaffold的主体,可以在其中添加各式各样的Widget来丰富应用。
floatingActionButton
floatingActionButton是一个悬浮按钮,位置默认在屏幕右下角。
drawer
drawer是一个左侧划出的抽屉,设置drawer是会默认在appBar的leading处添加按钮,并对这个按钮添加呼出drawer事件。
endDrawer
同drawer,endDrawer是一个右侧划出的抽屉,设置endDrawer是会默认在appBar的actions 处添加按钮,并对这个按钮添加呼出drawer事件。
bottomSheet
bottomSheet是一个底部弹出框,一般用于弹出分享列表。
bottomNavigationBar
bottomNavigationBar是底部导航栏,用于快速切换应用模块。
文本
Text
Text是普通文本组件,继承自StatelessWidget,源码如下:
/// Creates a text widget.
///
/// If the [style] argument is null, the text will use the style from the
/// closest enclosing [DefaultTextStyle].
///
/// The [data] parameter must not be null.
///
/// The [overflow] property's behavior is affected by the [softWrap] argument.
/// If the [softWrap] is true or null, the glyph causing overflow, and those that follow,
/// will not be rendered. Otherwise, it will be shown with the given overflow option.
const Text(
String 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,
this.textHeightBehavior,
})
其中常用参数:
- data:显示的内容
- style:样式
- textAlign:文本应如何水平对齐
- softWrap:某一行中文本过长,是否需要换行。默认为true,如果为false,需要设置overflow
- overflow:如何处理视觉溢出
- maxLines:最大行数
示例:
Text('标题',style: TextStyle(fontSize: 18,fontWeight: FontWeight.bold),),
RichText
RichText是富文本,继承自MultiChildRenderObjectWidget,是个RenderObjectWidget,源码如下:
/// Creates a paragraph of rich text.
/// The [text], [textAlign], [softWrap], [overflow], and [textScaleFactor]
/// arguments must not be null.
/// The [maxLines] property may be null (and indeed defaults to null), but if
/// it is not null, it must be greater than zero.
/// The [textDirection], if null, defaults to the ambient [Directionality],
/// which in that case must not be null.
RichText({
Key? key,
required this.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,
this.textHeightBehavior,
})
其中常用参数:
- text:返回一个TextSpan,在其中自定义内容和样式
- textAlign:文本应如何水平对齐
- softWrap:某一行中文本过长,是否需要换行。默认为true,如果为false,需要设置overflow
- overflow:如何处理视觉溢出
- maxLines:最大行数
示例:
RichText(
text: TextSpan(
children: <InlineSpan>[
TextSpan(text: '第一部分',style: TextStyle(color: Colors.red)),
TextSpan(text: ',第二部分,'),
TextSpan(text: '第三部分',style: TextStyle(color: Colors.red)),
]),
)
TextField
TextField 是个文本输入框,简单使用:
TextField(
decoration: InputDecoration(
hintText: '请输入用户名',
hintStyle: TextStyle(color: Colors.grey),
hintMaxLines: 1
),
)
图片
Image
Image用于显示图片,简单使用:
// 网络
Image.network(
'https://flutter.github.io/assets-for-api-docs/assets/widgets/puffin.jpg',
),
// 本地
Image.asset(
'assets/images/aa.jpg',
width: 150,
height: 150,
fit: BoxFit.none,
alignment: Alignment.centerRight,
),
列表
ListView
ListView是一个单数的列表组件,简单使用:
ListView(
children: <Widget>[
Text('标题1'),
Text('标题2'),
Text('标题3'),
Text('标题4'),
],
)
GridView
GridView是一个复数的列表组件,简单使用:
GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
children: [
Text('标题1'),
Text('标题2'),
Text('标题3'),
Text('标题4'),
],
)
Wrap
Warp是一个自适应的列表,简单使用:
Wrap(
spacing: 5,
runSpacing: 3,
crossAxisAlignment: WrapCrossAlignment.center,
children: List.generate(10, (i) {
double w = 50.0 + 10 * i;
double h = 50.0 + 5 * i;
return Container(
color: Colors.primaries[i],
height: h,
alignment: Alignment.center,
width: w,
child: Text('$i'),
);
}),
)
容器
Container 是最常用的组件之一,它是单容器类组件,仅能包含一个子组件,用于装饰和定位子组件,例如设置背景颜色、形状等。简单使用:
// 基础
Container(
child: Text('标题1'),
)
// 限定
Container(
height: 200,
width: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(
'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg'),
fit: BoxFit.cover,
),
border: Border.all(
color: Colors.blue,
width: 2,
),
borderRadius: BorderRadius.circular(12),
),
)
布局
线性(Row/Column )
Row 是将子组件以水平方式布局的组件, Column 是将子组件以垂直方式布局的组件。简单使用:
// 横向排列
Row(
children: <Widget>[
Container(
height: 50,
width: 100,
color: Colors.red,
),
Container(
height: 50,
width: 100,
color: Colors.green,
),
Container(
height: 50,
width: 100,
color: Colors.blue,
),
],
)
// 竖向排列
Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
height: 50,
width: 100,
color: Colors.red,
),
Container(
height: 50,
width: 100,
color: Colors.green,
),
Container(
height: 50,
width: 100,
color: Colors.blue,
),
],
)
叠加定位
叠加布局组件Stack, 组件将子组件叠加显示,根据子组件的顺序依次向上叠加,简单使用:
Stack(
children: <Widget>[
Container(
height: 200,
width: 200,
color: Colors.red,
),
Container(
height: 170,
width: 170,
color: Colors.blue,
),
Container(
height: 140,
width: 140,
color: Colors.yellow,
)
],
)
可使用Positioned进行定位:
Stack(
overflow: Overflow.visible,
children: <Widget>[
Container(
height: 200,
width: 200,
color: Colors.red,
),
Positioned(
left: 100,
top: 100,
height: 150,
width: 150,
child: Container(
color: Colors.green,
),
)
],
)
手势
GestureDetector
GestureDetector 是手势识别的组件,可以识别点击、双击、长按事件、拖动、缩放等手势。简单使用:
// 点击
GestureDetector(
onTapDown: (TapDownDetails tapDownDetails) {
print('onTapDown');
},
onTapUp: (TapUpDetails tapUpDetails) {
print('onTapUp');
},
onTap: () {
print('onTap');
},
onTapCancel: () {
print('onTapCancel');
},
child: Center(
child: Container(
width: 200,
height: 200,
color: Colors.red,
),
),
)
// 双击
GestureDetector(
onDoubleTap: ()=>print('onDoubleTap'),
child: Center(
child: Container(
width: 200,
height: 200,
color: Colors.red,
),
),
)
//长按事件
GestureDetector(
onLongPressStart: (v) => print('onLongPressStart'),
onLongPressMoveUpdate: (v) => print('onLongPressMoveUpdate'),
onLongPressUp: () => print('onLongPressUp'),
onLongPressEnd: (v) => print('onLongPressEnd'),
onLongPress: () => print('onLongPress'),
child: Center(
child: Container(
width: 200,
height: 200,
color: Colors.red,
),
),
)
// 拖动事件
GestureDetector(
onVerticalDragStart: (v) => print('onVerticalDragStart'),
onVerticalDragDown: (v) => print('onVerticalDragDown'),
onVerticalDragUpdate: (v) => print('onVerticalDragUpdate'),
onVerticalDragCancel: () => print('onVerticalDragCancel'),
onVerticalDragEnd: (v) => print('onVerticalDragEnd'),
child: Center(
child: Container(
width: 200,
height: 200,
color: Colors.red,
),
),
)
// 缩放事件
GestureDetector(
onScaleStart: (v) => print('onScaleStart'),
onScaleUpdate: (ScaleUpdateDetails v) => print('onScaleUpdate'),
onScaleEnd: (v) => print('onScaleEnd'),
child: Center(
child: Container(
width: 200,
height: 200,
color: Colors.red,
),
),
)
InkWell
InkWell 组件在用户点击时出现“水波纹”效果,简单使用:
InkWell(
onTap: (){},
child: Text('这是InkWell点击效果'),
)