脚手架(Scaffold)

脚手架Scaffold是Flutter UI中重要的组成部分,实现了大部分的APP页面需求,相当于房屋框体结构,页面一般都需要基于Scaffold来开发,主要成员包含:appBar(顶部Bar)、body(主体)、floatingActionButton(悬浮按钮)、drawer/endDrawer(抽屉)、bottomSheet(底部Sheet)、bottomNavigationBar(底部导航栏)。
412.jpg

appBar

appBar是Scaffold中的顶部工具栏,显示标题和添加一些便捷常用的工具/菜单。appBar接受PreferredSizeWidget,可自定bar,也可使用Flutter提供的AppBar(),AppBar的构成如下图,主要包含leading(导航)、title(标题)、actions(工具/菜单)、flexibleSpace(灵活空间)、bottom(底部扩展) 几个部分
五.组件 - 图2

  • 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,源码如下:

  1. /// Creates a text widget.
  2. ///
  3. /// If the [style] argument is null, the text will use the style from the
  4. /// closest enclosing [DefaultTextStyle].
  5. ///
  6. /// The [data] parameter must not be null.
  7. ///
  8. /// The [overflow] property's behavior is affected by the [softWrap] argument.
  9. /// If the [softWrap] is true or null, the glyph causing overflow, and those that follow,
  10. /// will not be rendered. Otherwise, it will be shown with the given overflow option.
  11. const Text(
  12. String this.data, {
  13. Key? key,
  14. this.style,
  15. this.strutStyle,
  16. this.textAlign,
  17. this.textDirection,
  18. this.locale,
  19. this.softWrap,
  20. this.overflow,
  21. this.textScaleFactor,
  22. this.maxLines,
  23. this.semanticsLabel,
  24. this.textWidthBasis,
  25. this.textHeightBehavior,
  26. })

其中常用参数:

  • data:显示的内容
  • style:样式
  • textAlign:文本应如何水平对齐
  • softWrap:某一行中文本过长,是否需要换行。默认为true,如果为false,需要设置overflow
  • overflow:如何处理视觉溢出
  • maxLines:最大行数

示例:

  1. Text('标题',style: TextStyle(fontSize: 18,fontWeight: FontWeight.bold),),

RichText

RichText是富文本,继承自MultiChildRenderObjectWidget,是个RenderObjectWidget,源码如下:

  1. /// Creates a paragraph of rich text.
  2. /// The [text], [textAlign], [softWrap], [overflow], and [textScaleFactor]
  3. /// arguments must not be null.
  4. /// The [maxLines] property may be null (and indeed defaults to null), but if
  5. /// it is not null, it must be greater than zero.
  6. /// The [textDirection], if null, defaults to the ambient [Directionality],
  7. /// which in that case must not be null.
  8. RichText({
  9. Key? key,
  10. required this.text,
  11. this.textAlign = TextAlign.start,
  12. this.textDirection,
  13. this.softWrap = true,
  14. this.overflow = TextOverflow.clip,
  15. this.textScaleFactor = 1.0,
  16. this.maxLines,
  17. this.locale,
  18. this.strutStyle,
  19. this.textWidthBasis = TextWidthBasis.parent,
  20. this.textHeightBehavior,
  21. })

其中常用参数:

  • text:返回一个TextSpan,在其中自定义内容和样式
  • textAlign:文本应如何水平对齐
  • softWrap:某一行中文本过长,是否需要换行。默认为true,如果为false,需要设置overflow
  • overflow:如何处理视觉溢出
  • maxLines:最大行数

示例:

  1. RichText(
  2. text: TextSpan(
  3. children: <InlineSpan>[
  4. TextSpan(text: '第一部分',style: TextStyle(color: Colors.red)),
  5. TextSpan(text: ',第二部分,'),
  6. TextSpan(text: '第三部分',style: TextStyle(color: Colors.red)),
  7. ]),
  8. )

TextField

TextField 是个文本输入框,简单使用:

  1. TextField(
  2. decoration: InputDecoration(
  3. hintText: '请输入用户名',
  4. hintStyle: TextStyle(color: Colors.grey),
  5. hintMaxLines: 1
  6. ),
  7. )

图片

Image

Image用于显示图片,简单使用:

  1. // 网络
  2. Image.network(
  3. 'https://flutter.github.io/assets-for-api-docs/assets/widgets/puffin.jpg',
  4. ),
  5. // 本地
  6. Image.asset(
  7. 'assets/images/aa.jpg',
  8. width: 150,
  9. height: 150,
  10. fit: BoxFit.none,
  11. alignment: Alignment.centerRight,
  12. ),

列表

ListView

ListView是一个单数的列表组件,简单使用:

  1. ListView(
  2. children: <Widget>[
  3. Text('标题1'),
  4. Text('标题2'),
  5. Text('标题3'),
  6. Text('标题4'),
  7. ],
  8. )

GridView

GridView是一个复数的列表组件,简单使用:

  1. GridView(
  2. gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  3. crossAxisCount: 2,
  4. ),
  5. children: [
  6. Text('标题1'),
  7. Text('标题2'),
  8. Text('标题3'),
  9. Text('标题4'),
  10. ],
  11. )

Wrap

Warp是一个自适应的列表,简单使用:

  1. Wrap(
  2. spacing: 5,
  3. runSpacing: 3,
  4. crossAxisAlignment: WrapCrossAlignment.center,
  5. children: List.generate(10, (i) {
  6. double w = 50.0 + 10 * i;
  7. double h = 50.0 + 5 * i;
  8. return Container(
  9. color: Colors.primaries[i],
  10. height: h,
  11. alignment: Alignment.center,
  12. width: w,
  13. child: Text('$i'),
  14. );
  15. }),
  16. )

五.组件 - 图3

容器

Container 是最常用的组件之一,它是单容器类组件,仅能包含一个子组件,用于装饰和定位子组件,例如设置背景颜色、形状等。简单使用:

  1. // 基础
  2. Container(
  3. child: Text('标题1'),
  4. )
  5. // 限定
  6. Container(
  7. height: 200,
  8. width: 200,
  9. decoration: BoxDecoration(
  10. image: DecorationImage(
  11. image: NetworkImage(
  12. 'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg'),
  13. fit: BoxFit.cover,
  14. ),
  15. border: Border.all(
  16. color: Colors.blue,
  17. width: 2,
  18. ),
  19. borderRadius: BorderRadius.circular(12),
  20. ),
  21. )

布局

线性(Row/Column )

Row 是将子组件以水平方式布局的组件, Column 是将子组件以垂直方式布局的组件。简单使用:

  1. // 横向排列
  2. Row(
  3. children: <Widget>[
  4. Container(
  5. height: 50,
  6. width: 100,
  7. color: Colors.red,
  8. ),
  9. Container(
  10. height: 50,
  11. width: 100,
  12. color: Colors.green,
  13. ),
  14. Container(
  15. height: 50,
  16. width: 100,
  17. color: Colors.blue,
  18. ),
  19. ],
  20. )
  21. // 竖向排列
  22. Column(
  23. mainAxisSize: MainAxisSize.min,
  24. children: <Widget>[
  25. Container(
  26. height: 50,
  27. width: 100,
  28. color: Colors.red,
  29. ),
  30. Container(
  31. height: 50,
  32. width: 100,
  33. color: Colors.green,
  34. ),
  35. Container(
  36. height: 50,
  37. width: 100,
  38. color: Colors.blue,
  39. ),
  40. ],
  41. )

叠加定位

叠加布局组件Stack, 组件将子组件叠加显示,根据子组件的顺序依次向上叠加,简单使用:

  1. Stack(
  2. children: <Widget>[
  3. Container(
  4. height: 200,
  5. width: 200,
  6. color: Colors.red,
  7. ),
  8. Container(
  9. height: 170,
  10. width: 170,
  11. color: Colors.blue,
  12. ),
  13. Container(
  14. height: 140,
  15. width: 140,
  16. color: Colors.yellow,
  17. )
  18. ],
  19. )

可使用Positioned进行定位:

  1. Stack(
  2. overflow: Overflow.visible,
  3. children: <Widget>[
  4. Container(
  5. height: 200,
  6. width: 200,
  7. color: Colors.red,
  8. ),
  9. Positioned(
  10. left: 100,
  11. top: 100,
  12. height: 150,
  13. width: 150,
  14. child: Container(
  15. color: Colors.green,
  16. ),
  17. )
  18. ],
  19. )

手势

GestureDetector

GestureDetector 是手势识别的组件,可以识别点击、双击、长按事件、拖动、缩放等手势。简单使用:

  1. // 点击
  2. GestureDetector(
  3. onTapDown: (TapDownDetails tapDownDetails) {
  4. print('onTapDown');
  5. },
  6. onTapUp: (TapUpDetails tapUpDetails) {
  7. print('onTapUp');
  8. },
  9. onTap: () {
  10. print('onTap');
  11. },
  12. onTapCancel: () {
  13. print('onTapCancel');
  14. },
  15. child: Center(
  16. child: Container(
  17. width: 200,
  18. height: 200,
  19. color: Colors.red,
  20. ),
  21. ),
  22. )
  23. // 双击
  24. GestureDetector(
  25. onDoubleTap: ()=>print('onDoubleTap'),
  26. child: Center(
  27. child: Container(
  28. width: 200,
  29. height: 200,
  30. color: Colors.red,
  31. ),
  32. ),
  33. )
  34. //长按事件
  35. GestureDetector(
  36. onLongPressStart: (v) => print('onLongPressStart'),
  37. onLongPressMoveUpdate: (v) => print('onLongPressMoveUpdate'),
  38. onLongPressUp: () => print('onLongPressUp'),
  39. onLongPressEnd: (v) => print('onLongPressEnd'),
  40. onLongPress: () => print('onLongPress'),
  41. child: Center(
  42. child: Container(
  43. width: 200,
  44. height: 200,
  45. color: Colors.red,
  46. ),
  47. ),
  48. )
  49. // 拖动事件
  50. GestureDetector(
  51. onVerticalDragStart: (v) => print('onVerticalDragStart'),
  52. onVerticalDragDown: (v) => print('onVerticalDragDown'),
  53. onVerticalDragUpdate: (v) => print('onVerticalDragUpdate'),
  54. onVerticalDragCancel: () => print('onVerticalDragCancel'),
  55. onVerticalDragEnd: (v) => print('onVerticalDragEnd'),
  56. child: Center(
  57. child: Container(
  58. width: 200,
  59. height: 200,
  60. color: Colors.red,
  61. ),
  62. ),
  63. )
  64. // 缩放事件
  65. GestureDetector(
  66. onScaleStart: (v) => print('onScaleStart'),
  67. onScaleUpdate: (ScaleUpdateDetails v) => print('onScaleUpdate'),
  68. onScaleEnd: (v) => print('onScaleEnd'),
  69. child: Center(
  70. child: Container(
  71. width: 200,
  72. height: 200,
  73. color: Colors.red,
  74. ),
  75. ),
  76. )

InkWell

InkWell 组件在用户点击时出现“水波纹”效果,简单使用:

  1. InkWell(
  2. onTap: (){},
  3. child: Text('这是InkWell点击效果'),
  4. )