Flutter五:Flutter基础Widget
目录
- 文本和字体
- 按钮
- 图片和Icon
- 单选框和复选框
- 输入框和表单
- 进度指示器
基础Widget
一、文本和字体
文本组件( tex )负责显示文本和定义显示样式,类似Android中的TextView。
Text(
"This is a page NewRoute" * 8,//显示8个text
maxLines: 20,
textAlign: TextAlign.center,
overflow: TextOverflow.clip,
textScaleFactor: 2,
style: TextStyle(
//字体颜色
color: Colors.white,
//字体大小
fontSize: 18,
//行高因子
height: 1.2,
//字体
fontFamily: "Courier",
//字体背景
background: new Paint()
..color = Colors.amber,
//分割线
decoration: TextDecoration.overline,
//分割线风格:wavy-波浪,dashed-间隔线,double-双实线,dotted-小点线,
decorationStyle: TextDecorationStyle.solid,
//分割线颜色
decorationColor: Colors.purple,
),
),
二、按钮
①RaisedButton:漂浮按钮,默认带有阴影和灰色背景。按下后,阴影会变大
RaisedButton(
//背景颜色
color: Colors.red,
//正常的阴影
elevation: 8,
//按下时的阴影
highlightElevation: 8.0,
onPressed: () {
Navigator.pop(context);
},
child: Text('返回'),
),
②FlatButton:扁平按钮,默认背景透明并不带阴影。按下后,会有背景色
FlatButton(
child: Text("normal"),
onPressed: () {},
)
③OutlineButton:默认有一个边框,不带阴影且背景透明。按下后,边框颜色会变亮、同时出现背景和阴影(较弱)
OutlineButton(
child: Text("normal"),
onPressed: () {},
)
④IconButton:一个可点击的Icon,不包括文字,默认没有背景,点击后会出现背景
IconButton(
icon: Icon(Icons.thumb_up),
onPressed: () {},
)
⑤带图标的按钮:RaisedButton、FlatButton、OutlineButton都有一个icon 构造函数,通过它可以轻松创建带图标的按钮
RaisedButton.icon(
icon: Icon(Icons.send),
label: Text("发送"),
onPressed: _onPressed,
),
OutlineButton.icon(
icon: Icon(Icons.add),
label: Text("添加"),
onPressed: _onPressed,
),
FlatButton.icon(
icon: Icon(Icons.info),
label: Text("详情"),
onPressed: _onPressed,
),
⑥自定义按钮外观:按钮外观可以通过其属性来定义,不同按钮属性大同小异,我们以FlatButton为例
FlatButton(
color: Colors.blue,
highlightColor: Colors.blue[700],
colorBrightness: Brightness.dark,
splashColor: Colors.grey,
child: Text("Submit"),
shape:RoundedRectangleBorder(borderRadius: BorderRadius.circular(20.0)),
onPressed: () {},
)
三、图片
- 说明
- Flutter中,使用Image组件来加载并显示图片,可以是asset、文件、内存以及网络等数据。
- ImageProvider
ImageProvider 是一个抽象类,主要定义了图片数据获取的接口load(),从不同的数据源获取图片需要实现不同的ImageProvider ,如AssetImage是实现了从Asset中加载图片的ImageProvider,而NetworkImage实现了从网络加载图片的ImageProvider。 - Image
Image widget有一个必选的image参数,它对应一个ImageProvider。
Image属性表
属性名称 | 类型 | 说明 |
---|---|---|
alignment | AlignmentGeometry | 图像边界内对齐图像。 |
centerSlice | Rect | 九片图像的中心切片。 |
color | Color | 该颜色与每个图像像素混合colorBlendMode。 |
colorBlendMode | BlendMode | 用于 color 与此图像结合使用。 |
fit | BoxFit | 图像在布局中分配的空间。 |
gaplessPlayback | bool | 当图像提供者发生变化时,是继续显示旧图像(true)还是暂时不显示(false)。 |
image | ImageProvider | 要显示的图像。 |
matchTextDirection | bool | 是否在图像的方向上绘制图像 TextDirection。 |
repeat | ImageRepeat | 未充分容器时,是否重复图片。 |
height | double | 图像的高度。 |
width | double | 图像的宽度。 |
BoxFit取值表
属性名称 | 样式 |
---|---|
BoxFit.contain | 全图居中显示但不充满,显示原比例 |
BoxFit.cover | 图片可能拉伸,也可能裁剪,但是充满容器 |
BoxFit.fill | 全图显示且填充满,图片可能会拉伸 |
BoxFit.fitHeight | 图片可能拉伸,可能裁剪,高度充满 |
BoxFit.fitWidth | 图片可能拉伸,可能裁剪,宽度充满 |
BoxFit.scaleDown | 效果和contain差不多, 但是只能缩小图片,不能放大图片 |
- 从assets中加载图片
①在工程根目录下创建一个images目录,并将图片avatar.png拷贝到该目录。
②在pubspec.yaml中的flutter部分添加如下内容:
assets:
- images/avatar.png
- 注意: 由于 yaml 文件对缩进严格,所以必须严格按照每一层两个空格的方式进行缩进,此处assets前面应有两个空格。
③加载该图片
Image(
image: AssetImage("images/avatar.png"),
width: 100.0
);
Image也提供了一个快捷的构造函数Image.asset用于从asset中加载、显示图片:
Image.asset("images/avatar.png",
width: 100.0,
)
- 从网络加载图片
Image(
image: NetworkImage(
"http://ww4.sinaimg.cn/large/7a8aed7bjw1exp4h479xfj20hs0qoq6t.jpg"),
width: 100.0,
)
Image也提供了一个快捷的构造函数Image.network用于从网络加载、显示图片:
Image.network(
"http://ww4.sinaimg.cn/large/7a8aed7bjw1exp4h479xfj20hs0qoq6t.jpg",
width: 100.0,
)
- 圆形与圆角
Image 是不支持圆角和阴影的,目前可以通过使用 CircleAvatar 和 Container 实现。
- 圆形方式一:
CircleAvatar(
backgroundImage: NetworkImage("http://ww4.sinaimg.cn/large/7a8aed7bjw1exp4h479xfj20hs0qoq6t.jpg"),
),
- 圆形方式二:
Container(
width: 100.0,
height: 100.0,
decoration: BoxDecoration(
shape: BoxShape.circle,
image: DecorationImage(
image: NetworkImage("http://ww4.sinaimg.cn/large/7a8aed7bjw1exp4h479xfj20hs0qoq6t.jpg"),
fit: BoxFit.cover)),
),
- 圆角
Container(
width: 100.0,
height: 100.0,
decoration: BoxDecoration(
shape: BoxShape.rectangle,//这里需要设置为 rectangle
borderRadius: BorderRadius.all(Radius.circular(20)),//rectangle 时,BorderRadius 才有效
image: DecorationImage(
image: NetworkImage("http://ww4.sinaimg.cn/large/7a8aed7bjw1exp4h479xfj20hs0qoq6t.jpg"),
fit: BoxFit.cover)),
)
四、 Icon
- 简介
Flutter中,Icon是将图标做成字体文件,然后通过指定不同的字符而显示不同的图片。
在字体文件中,每一个字符都对应一个位码,而每一个位码对应一个显示字形,不同的字体就是指字形不同,即字符对应的字形是不同的。而在iconfont中,只是将位码对应的字形做成了图标,所以不同的字符最终就会渲染成不同的图标。
在Flutter开发中,iconfont和图片相比有如下优势:
①体积小:可以减小安装包大小。
②矢量的:iconfont都是矢量图标,放大不会影响其清晰度。
③可以应用文本样式:可以像文本一样改变字体图标的颜色、大小对齐等。
④可以通过TextSpan和文本混用。
- 使用
Icon(
Icons.home,
)
ListTile(
leading: Icon(
Icons.person_add,
color: Colors.red,
),
title: Text('登录'),
onTap: () {},
)
五、单选框和复选框
Material 组件库中提供了Material风格的单选开关Switch和复选框Checkbox,虽然它们都是继承自StatefulWidget,但它们本身不会保存当前选中状态,选中状态都是由父组件来管理的。当Switch或Checkbox被点击时,会触发它们的onChanged回调,我们可以在此回调中处理选中状态改变逻辑。下面看一个简单的例子:
class SwitchAndCheckBoxTestRoute extends StatefulWidget {
@override
_SwitchAndCheckBoxTestRouteState createState() => new _SwitchAndCheckBoxTestRouteState();
}
class _SwitchAndCheckBoxTestRouteState extends State<SwitchAndCheckBoxTestRoute> {
bool _switchSelected=true; //维护单选开关状态
bool _checkboxSelected=true;//维护复选框状态
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Switch(
value: _switchSelected,//当前状态
onChanged:(value){
//重新构建页面
setState(() {
_switchSelected=value;
});
},
),
Checkbox(
value: _checkboxSelected,
activeColor: Colors.red, //选中时的颜色
onChanged:(value){
setState(() {
_checkboxSelected=value;
});
} ,
)
],
);
}
}
- 属性及外观
Switch和Checkbox属性比较简单,读者可以查看API文档,它们都有一个activeColor属性,用于设置激活态的颜色。至于大小,到目前为止,Checkbox的大小是固定的,无法自定义,而Switch只能定义宽度,高度也是固定的。值得一提的是Checkbox有一个属性tristate ,表示是否为三态,其默认值为false ,这时Checkbox有两种状态即“选中”和“不选中”,对应的value值为true和false 。如果tristate值为true时,value的值会增加一个状态null,读者可以自行了解。
六、 输入框和表单
Material组件库中提供了输入框组件TextField和表单组件Form。
-
TextField
-
Form
七、 进度指示器
Material 组件库中提供了两种进度指示器:LinearProgressIndicator和CircularProgressIndicator,它们都可以同时用于精确的进度指示和模糊的进度指示。精确进度通常用于任务进度可以计算和预估的情况,比如文件下载;而模糊进度则用户任务进度无法准确获得的情况,如下拉刷新,数据提交等。
轮播图
- 如果放在column中,必须使用container包裹swiper
- container高度可以写死,但是无法适配所有手机,我们可以使用aspectRadio
Container(
width: double.infinity,
child: AspectRatio(
aspectRatio: 16/9,
child: Swiper(
itemBuilder: (BuildContext contxt, int index) {
return Image.network(imgs[index], fit: BoxFit.cover);
},
itemCount: imgs.length,
pagination: SwiperPagination(),
//显示indicator
// control: SwiperControl(), //显示箭头
loop: true,
autoplay: true,
),
)),