Flutter 常见Widgets使用(全网最全)

  • Container(Single-Child)单一元素组件【child】

  • Row、Column多元素组件【child】

  • Icon:矢量图标字体:iconFont:

    • 优势:
      • 尺寸不管怎么变,图标本身都是清晰的,且没有锯齿,
      • 可以修改颜色:
      • 还支持传入图片 (icon: 'images/icon.png')
    • 缺点:只能设置纯色,不能设置渐变色
  • Image 图片加载

    • 本地AssetImage AssetImage('images/image_icon.png')
    • 网络图:NetworkImage NetworkImage('imageUrl')
    • 文件中加载: Image.file
    • 内存中加载: Image.memory
    • 每种方式继承了各自的ImageProvider
  • Button

    • RaisedButton 点击带波纹效果,且有阴影
    RaisedButton(
            color: Colors.blue,
            child: Text("RaisedButton"),
            textColor: Colors.white,
            onPressed: () => {},
          ),
    
    • FloatButton: 没有背景
    FlatButton(
            textColor: Colors.blue,
            child: Text("FloatButton"),
            onPressed: () {
              print("FlatButton");
            },
          ),
    
    • OutlineButton: 带边框按钮,点击时边框和背景颜色呈现高亮状态
    OutlineButton(
            textColor: Colors.blue,
            child: Text("OutlineButton"),
            onPressed: () {
              print("OutlineButton");
            },
          ),
    
    • FloatingActionButton:一般一个界面只有一个,用于分享,导航
    FloatingActionButton(
            child: Text("F"),
            onPressed: () {
              print("F");
            },
          )
    
    • 自定义按钮:找到其父类,重写相关属性
      效果图
  • FlutterLogo:顾名思义Flutter的Logo,传入size可改变logo的大小,可以做定位

1.SingleChild

①.Container

  • 对其方式:alignment 范围(-1,1)
    • 左上角:(-1,-1)
    • 右上角:(1,-1)
    • 左下角:(-1,1)
    • 右下角:(1,1)
    • 中间:(0,0)
  • 设置约束
    • BoxConstraint(minWidth、minHeight、maxWidth、maxHeight)
```dart
Container(
  color: Colors.green,
  alignment: Alignment(0.0, 0.0),
  child: new Text("Container"),
  constraints: BoxConstraints(
      maxHeight: 300.0,
      maxWidth: 300.0,
      minWidth: 200.0,
      minHeight: 120.0),
)
```
  • Container中child设置最大 BoxConstraints.expand
Container(
    color: Colors.blue,
    child: Text("Flutter"),
    constraints: BoxConstraints.expand(),
  )
  • expand中可以设定容器的宽高
constraints: BoxConstraints.expand(width: 250.0, height: 100.0),
  • margin(外边距) 和 padding(内边距)
margin: EdgeInsets.only(top: 60.0),
padding: EdgeInsets.only(top: 60.0),
//EdgeInsets 其他写法
EdgeInsets.symmetric('对称')
EdgeInsets.fromLTRB(位置)
EdgeInsets.all(全部)
  • decoration 装饰器
    • 支持背景图 image:
    • 渐变色 gradient: LinearGradient()
    • 圆角 borderRadius
    • 阴影 boxShadow
    • 旋转 transform: Matrix4.rotationZ(.3),
    • 边框 border: Border.all(width: 3, color: Color(0xffaaaaaa))

②SingleChildScrollView-滚动布局

  • 组件是负责滚动的,里面只能嵌套一个组件
  • Column布局超出屏幕后不能滚动,需要在外层嵌套SingleChildScrollView才可以
  • 可以设置滚动方向,也可以通过reverse 属性设置阅读顺序
  • 还可以解决TextField布局溢出问题

③FittedBox 缩放

负责对组件进行缩放和位置调整

  • fit 缩放方式 缩放本身占据FittedBox的大小,默认值BoxFit.contain
    • 子组件的宽度或高度被缩放到父容器限定的值时,就会被停止缩放
  • alignment 对齐方式
 Row(
    children: <Widget>[
      Container(
        color: Colors.blue,
        width: 80.0,
        height: 80.0,
        margin: EdgeInsets.only(bottom: 10.0),
        child: new FittedBox(
          fit: BoxFit.contain,
          alignment: Alignment.topLeft,
          child: new Container(
            color: Colors.yellow,
            child: new Text("FittedBox"),
          ),
        ),
      ),
      Text(
        "BoxFit.contain",
        style: new TextStyle(fontSize: 20.0),
      )
    ],
  )
15730043034089.jpg

④FractionallySizedBox 宽度和高度缩放

  • 基于宽度缩放因子和高度缩放因子来调整布局
  • 大小有可能超出其父组件的设置
  • 如果FractionallySizedBox中子组件设置了大小,则不会起作用,会被覆盖掉
Container(
    color: Colors.blue,
    height: 130.0,
    width: 130.0,
    padding: EdgeInsets.all(5.0),
    child: new FractionallySizedBox(
      alignment: Alignment.topLeft,
      widthFactor: 1.5,
      heightFactor: 0.5,
      child: new Container(
        color: Colors.yellow,
      ),
    ),
  )
15730905004805.jpg

⑤ConstrainedBox-限制约束

  • 在其约定范围内,其子组件是不能逾越的
  • ConstrainedBox中主要是constraints起作用,而且这个值不能为null(空)
ConstrainedBox(
    constraints: BoxConstraints(
      minWidth: 100.0,
      minHeight: 100.0,
      maxWidth: 250.0,
      maxHeight: 250.0,
    ),
    child: new Container(
      width: 500.0,
      height: 300.0,
      color: Colors.blue,
      child: Text(
        "100010001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000",
        style: new TextStyle(color: Colors.black, fontSize: 20.0),
        // 设置省略号
        overflow: TextOverflow.ellipsis,
        // 设置最大行数
        maxLines: 1,
      ),
    ),
  )
15730911486040.jpg

⑥BaseLine

  • 一种基线的对其方式,把不相关的几个组件设置在同一条水平线上进行对齐
  • baseline 设置位置,单位是浮点型(不能为空)
  • baselineType 不能为空
Row(
    mainAxisAlignment: MainAxisAlignment.spaceBetween,
    children: <Widget>[
      new Baseline(
        baseline: 80.0,
        baselineType: TextBaseline.alphabetic,
        child: new Text(
          '今天天气真好',
          style: new TextStyle(
            fontSize: 18.0,
            color: Colors.red,
            textBaseline: TextBaseline.alphabetic,
          ),
        ),
      ),
      new Baseline(
        baseline: 100.0,
        baselineType: TextBaseline.alphabetic,
        child: new Text(
          '适合晨练',
          style: new TextStyle(
            fontSize: 30.0,
            color: Colors.blue,
            textBaseline: TextBaseline.alphabetic,
          ),
        ),
      ),
      new Baseline(
        baseline: 120.0,
        baselineType: TextBaseline.alphabetic,
        child: FlutterLogo(
          size: 100,
        ),
      ),
    ],
  )
效果图

2.Multi-Child 多元素组件

①Scaffold

Scaffold 是基于Material的一个标准化的布局容器

  • 常见属性
    • AppBar
    • body
    • bottomNavigationBar
    • floatingActionButton
    • drawer ...

②AppBar

顶部导航栏,用于控制App的路由、显示标题栏,返回按钮以及右侧操作栏(屏幕顶端)

  • 常见属性
    • leading 返回按钮
    • title 标题组件
    • actions 右侧按钮组件
    • flexibleSpace
    • bottom 底部区域
效果图
class AppBarWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('本地优惠'),
        leading: IconButton(
            icon: new Icon(Icons.face),
            onPressed: () {
              Navigator.pop(context);
            }),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.playlist_play),
            tooltip: 'tooltip1',
            onPressed: () {},
          ),
          IconButton(
            icon: Icon(Icons.playlist_add),
            tooltip: 'tooltip2',
            onPressed: () {},
          ),
          IconButton(
            icon: Icon(Icons.playlist_add_check),
            tooltip: 'tooltip3',
            onPressed: () {},
          ),
        ],
      ),
      body: Column(
        children: <Widget>[
          FlutterLogo(
            size: 100.0,
            colors: Colors.red,
          )
        ],
      ),
    );
  }
}
效果图

③Row 和 Column 水平和纵向布局

  • Column 不支持滚动,想支持滚动,需要考虑使用ListView
  • crossAxisAlignment 子组件在纵轴的对其方式
  • mainAxisAlignment 子组件在水平方向的对其方式
  • textDirection 布局顺序,从左至由,从右至左
  • mainAxisSize max 表示尽可能多地占用水平方向位置,min 则反之

注意

  • 在Row 和 Column 里CrossAxis 和 Main Axis 是不一样的
  • Row 布局 设置 crossAxisAlignment 无效
  • Column 布局 设置 mainAxisAlignment 无效
    效果图

④ListView

构建方式

  • ListView
    • itemExtent 预估行高
    • shrinkWrap 是否根据子组件的高度来设置ListView的高度, 默认为false
    • RepaintBoundry 当addRepaintBoundres为 true时,避免列表滚动式重绘
    • AutomaticKeepAlive 当 addAutomaticKeepAlive为 true时,则ListView被划出的区域不被回收
    • scrollDirection: 设置组件滚动方向 (Axis.horizontal)
    • 不指定itemCount,列表无限长
    • physics:是否可滑动
      • NeverScrollablePhysics (不滚动)
      • BouncingScrollPhysics (iOS 效果)
      • ClampingScrollPhysics (Android 效果)
      • FixedExtentScrollPhysics (固定范围滚动)
        • ListWheelScrollView 效果类似iOS PickerView
          效果图
  • ListView.builder:IndexedWidgetBuilder,只返回一个组件
  • ListView.bottom
  • ListView.separated 分割线,区头,区位
  • ListView.custom,通过SilverChildListDelegate来接收IndexedWidgetBuilder

⑤GridView网格布局

1.GridView.count

  • 初始化方法GridView.count
  • crossAxisSpacing: 水平子Widget之间间距
  • mainAxisSpacing: 垂直子Widget之间间距
  • padding: GridView内边距
  • crossAxisCount :一行的Widget数量
  • childAspectRatio :子Widget宽高比例
  • children : 子Widget列表
GridView.count(
  //水平子Widget之间间距
  crossAxisSpacing: 10.0,
  //垂直子Widget之间间距
  mainAxisSpacing: 30.0,
  //GridView内边距
  padding: EdgeInsets.all(10.0),
  //一行的Widget数量
  crossAxisCount: 2,
  //子Widget宽高比例
  childAspectRatio: 2.0,
  //子Widget列表
  children: getWidgetList(),
);

2.GridView.builder

@override
  Widget build(BuildContext context) {
    List<String> datas = getDataList();
    return GridView.builder(
        itemCount: datas.length,
        //SliverGridDelegateWithFixedCrossAxisCount 构建一个横轴固定数量Widget
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        //横轴元素个数
        crossAxisCount: 3,
        //纵轴间距
        mainAxisSpacing: 20.0,
        //横轴间距
        crossAxisSpacing: 10.0,
        //子组件宽高长度比例
        childAspectRatio: 1.0),
        itemBuilder: (BuildContext context, int index) {
          //Widget Function(BuildContext context, int index)
          return getItemContainer(datas[index]);
        });
  }
效果图

⑥CustomScrollView

两个组件结合起来形成一个滚动区域

import 'package:flutter/material.dart';
class CustomScrollViewWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: CustomScrollView(
        slivers: <Widget>[
          const SliverAppBar(
            pinned: true,
            expandedHeight: 250.0,
            flexibleSpace: FlexibleSpaceBar(
              title: Text('Demo'),
            ),
          ),
          SliverGrid(
            gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
              maxCrossAxisExtent: 200.0,
              mainAxisSpacing: 10.0,
              crossAxisSpacing: 10.0,
              childAspectRatio: 4.0,
            ),
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  alignment: Alignment.center,
                  color: Colors.teal[100 * (index % 9)],
                  child: Text('grid item $index'),
                );
              },
              childCount: 20,
            ),
          ),
          SliverFixedExtentList(
            itemExtent: 50.0,
            delegate: SliverChildBuilderDelegate(
              (BuildContext context, int index) {
                return Container(
                  alignment: Alignment.center,
                  color: Colors.lightBlue[100 * (index % 9)],
                  child: Text('list item $index'),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

组件转换

  • AppBar -> SliverAppBar
  • GridView -> SliverGrid
  • ListView -> SliverFixedExtentList
  • 转换后的组件都是以(Sliver)开头的,其本身是不具备滚动特征的,但是当放在CustomScrollView中之后,则可以实现滚动的功能
效果图
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容