本篇文章咱们来说讲一些比较经常使用的 Widget。数组
你们验证的时候使用下面的代码替换 main.dart 代码,而后在 //TODO 语句返回下面经常使用 Widget 示例的代码。网络
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Center( child: _buildWidget(), ), ), ); } Widget _buildWidget() { //TODO } }
1)基本使用less
return Text('Show Regular Text');
2)设置字体样式ide
属性:style布局
设置粗体:学习
return Text( 'Show Bold Text', style: TextStyle(fontWeight: FontWeight.bold), );
设置颜色:测试
return Text( 'Show Bold Red Text', style: TextStyle(fontWeight: FontWeight.bold, color: Colors.red), );
其余样式相信你们学习过以前的文章,知道如何查看一个 Widget 源码以及如何使用了。字体
3)设置最大行数及省略号ui
属性:maxLines、overflowthis
return Container( width: 100, child: Text( '设置文本超过 100,这样可以看到效果,这里设置最多显示一行', maxLines: 1, //设置最大行数 overflow: TextOverflow.ellipsis, //设置超过显示省略号 ), );
大概效果以下:
1)本地加载图片
第一步:建立放置图片的文件夹,这里假设咱们在 my_flutter 下面建立 assets/images/2.0x 和 assets/images/3.0x 文件夹用于存放本地图片。
第二步:拷贝图片 wechat.png 到上述文件夹,通常若是切图是用 sketch,则直接选择对应的 2 倍图和 3 倍图。
第三步:在 pubspec.yaml 文件肯定要使用的图片资源位置。这里能够定义以下:
assets: - assets/images/wechat.png
第四步:使用以下。
return Image.asset('assets/images/wechat.png')
可能有小伙伴会以为,若是我有不少图片须要使用,是否是每次执行第三步和第四步的时候都要写那么长的路径。
先说下第四步,若是你都是同个目录,只是最后图片名称不同。那么你能够自定义一个包装类作一层包装。
接着咱们来讲下第三步的状况。
假设你有不少图片在同一个文件夹下面,那么你是能够在 pubspec.yaml 里面使用目录定义的。可是,注意官方文档的一句话:
Note that only files located directly in the directory will be included; to add files located in subdirectories, create an entry per directory.
简单的说就是你使用的目录要到最底层,也就是这个目录下面就是图片而不是目录了。
举咱们这个例子就是若是你要用目录定义及使用,上面第三步替换为
assets: - assets/images/2.0x/
第四步替换为
return Image.asset('assets/images/2.0x/wechat.png');
能够看到这样咱们若是一张图片要适配不一样尺寸估计就不是很合适了。
所以对于有适配场景的,其实推荐第一种直接配置指定图片的方式。
舒适提示:
修改 pubspec.yaml 文件以后建议运行以前增长清理工做。
好比以前是执行 flutter run
修改以后建议执行 flutter packages get;flutter clean;flutter run
上面定义的位置能够直接在 pubspec.yaml 文件搜索 assets,有注释讲解的位置就是你要添加的位置了。
官网:
https://flutter.dev/docs/development/ui/assets-and-images#loading-images
2)网络加载图片
给定一个图片 url,执行下面代码便可:
return Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240');
3)指定宽高
指定宽高是直接使用 width 和 height 属性。
好比网络加载图片指定宽高以下:
return Image.network( 'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240', width: 300, height: 200, );
大体效果以下:
前面两个讲的都是单个小组件。接下来咱们讲的是相似于布局的组件。(仍是组件,毕竟 Flutter 一切皆 Widget)
1)基本使用
你们看到这个词,应该会直观认为这个就是对于一些布局为列的场景吧,可能有多列,然而不是哦。
点进去源码能够看到以下注释:
/// Creates a vertical array of children.
大概意思是建立一组垂直的子组件集合。
若是你是 Android 开发,能够联想到 LinearLayout 里面的 orientation 设置为 vertical 时的布局。
以下:
你也能够这样记忆,Column 是列,说明布局只有一列。因此就是上面这种了。
因此上面的 Text 效果图和 Image 效果图应该就知道是如何显示了吧?
咱们这里给下示例代码,固然若是你是用带刘海屏的设备运行,可能顶部会看不到。后面咱们会继续说明。
return Column( children: <Widget>[ Image.asset('assets/images/wechat.png'), Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'), Image.network( 'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240', width: 300, height: 200, ) ], );
效果以下:
写法也很简单,就是设置一下 children 属性就能够了。
而后里面的 Widget 数组填充咱们要展现的 Widget 便可。
上面说了刘海屏设备顶部会看不到,那怎么办?
2)mainAxisAlignment
mainAxisAlignment 你能够认为是主轴的对齐方式。对于竖直的 Column,那就是竖直方向的对齐。
影响整个 Column
所以能够设置以下:
return Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Image.asset('assets/images/wechat.png'), Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'), Image.network( 'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240', width: 300, height: 200, ) ], );
你就会发现整个 Column 在竖直方向都居中了。
3)crossAxisAlignment
crossAxisAlignment 你能够认为是交叉轴的对齐方式,对于竖直的 Column,那就是水平方向的对齐。
影响 Column 里面的每个 Widget
设置以下:
return Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.end, children: <Widget>[ Image.asset('assets/images/wechat.png'), Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'), Image.network( 'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240', width: 300, height: 200, ) ], );
你会发现本来最后一张居中的图片在水平方向向右边对齐。
1)基本使用
/// Creates a horizontal array of children.
大概意思是建立一组水平的子组件集合,能够联想到 LinearLayout 里面的 orientation 设置为 horizontal 时的布局。
也能够记忆为 Row 表明行,所以只有一行。
以下:
Sample:
return Row( children: <Widget>[ Text('Widget One', style: TextStyle(color: Colors.blue),), Text('Widget Two'), ], );
效果以下:
能够看到只有一行,因此使用 Row。
写法也是比较简单,就是设置一下 children 属性就能够了。
而后里面的 Widget 数组填充咱们要展现的 Widget 便可。
2)mainAxisAlignment
mainAxisAlignment 你能够认为是主轴的对齐方式,对于水平的 Row,那就是水平方向的对齐。
影响整个 Row
所以能够设置以下:
return Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text('Widget One', style: TextStyle(color: Colors.blue),), Text('Widget Two'), ], );
这样效果显示就是上图居中。
3)crossAxisAlignment
crossAxisAlignment 你能够认为是交叉轴的对齐方式,对于水平的 Row,那就是竖直方向的对齐。
影响 Row 里面的每个 Widget
设置以下:(这里引入了一个后面才会讲到的 Widget,你们能够暂时不理,看下效果)
return Container( width: 300, height: 300, color: Colors.grey, child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.end, children: <Widget>[ Container( width: 100, height: 100, color: Colors.blue, child: Text( 'Widget One', ), ), Container( width: 100, height: 100, color: Colors.yellow, child: Text( 'Widget Two', ), ), ], ), );
灰色是咱们的父容器,能够看到两个控件水平方面居中,竖直方面向下对齐。
Container 的使用超级普遍。
咱们这里略微讲一下一些使用场景。
1)给一些没有自带宽高的属性设置宽高。
好比咱们上面讲到 Row 最后一个 Sample 的时候,给 Text、Row 设置宽高都是在外面套一层 Container。
2) 设置间距。
以上面 Column 的三张图片为例,他们一开始是下面代码:
return Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Image.asset('assets/images/wechat.png'), Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'), Image.network( 'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240', width: 300, height: 200, ) ], );
效果以下:
咱们但愿第一张和第二张图片有点距离,能够这样设置:
return Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Image.asset('assets/images/wechat.png'), Container( padding: EdgeInsets.only(top: 20.0), child: Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'), ), Image.network( 'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240', width: 300, height: 200, ) ], );
效果以下:
咱们代码里面使用 Container 都是把 Widget 拿出来做为 Container 的 child。
这里的 padding 使用有三种经常使用写法:
第一种:上下左右 padding 的值都同样
源码:
const EdgeInsets.all(double value) : left = value, top = value, right = value, bottom = value;
第二种:上下左右 padding 不一致或者只想设置某一个或某几个方向
源码:
const EdgeInsets.only({ this.left = 0.0, this.top = 0.0, this.right = 0.0, this.bottom = 0.0 });
第三种:设置水平或者垂直方向的 padding
源码:
const EdgeInsets.symmetric({ double vertical = 0.0, double horizontal = 0.0 }) : left = horizontal, top = vertical, right = horizontal, bottom = vertical;
相信如今给出源码,你们都知道怎么写了。
记得花括号是可选参数哈~
Sample:
padding: EdgeInsets.all(left : 20.0), padding: EdgeInsets.only(left : 20.0), padding: EdgeInsets.symmetric(horizontal : 20.0),
margin 和 padding 也是相似的,区别相信学过 Android 的都知道,你也能够本身测试一下区别,这里就不赘余了。
另外注意 Container 源码有个注释:
/// The `height` and `width` values include the padding.
举个例子就是假设有一张图片宽 100,假设你左右预留 padding 10,那么你宽须要设置为 120。
你能够用来替换须要套一层 Container 来设置 margin 或者 padding 的 Widget。
好比上面的代码
return Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Image.asset('assets/images/wechat.png'), Container( padding: EdgeInsets.only(top: 20.0), child: Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'), ), Image.network( 'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240', width: 300, height: 200, ) ], );
能够等效替换为
return Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Image.asset('assets/images/wechat.png'), SizedBox( height: 20.0, ), Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'), Image.network( 'https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240', width: 300, height: 200, ) ], );
将
Container( padding: EdgeInsets.only(top: 20.0), child: Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'), ),
替换成了
SizedBox( height: 20.0, ), Image.network('https://upload-images.jianshu.io/upload_images/5361063-cfad13c672a06084.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240'),
固然这里因为 Widget 没有限制宽高,因此 padding 或者 margin 在这里起到同样做用。
严格来讲 SizedBox 应该是替换 margin。替换 padding 须要注意上面说的宽高影响。
经常使用的 Widget 咱们就介绍到这里。
其余的咱们后续再介绍或者你们自行查阅官网 Widget 集合。
相信如今的你能够根据官网的 Sample 和说明以及亲自测试快速掌握新 Widget 的使用。
官网 Widget 集合:
https://flutter.dev/docs/development/ui/widgets
更多阅读:
Flutter 即学即用系列博客——01 环境搭建
Flutter 即学即用系列博客——02 一个纯 Flutter Demo 说明
Flutter 即学即用系列博客——03 在旧有项目引入 Flutter
Flutter 即学即用系列博客——04 Flutter UI 初窥
Flutter 即学即用系列博客——05 StatelessWidget vs StatefulWidget