image
介绍
Image, 图片显示Widget, 和Android ImageView相似,但是从实际使用的方法上看,与常用的图片加载库,如Picasso,Glide等相似,支持本地图片,资源图片,网络图片等加载方式。
类结构
构造方法
方式 | 解释 |
---|---|
Image() | 通用方法,使用ImageProvider实现,如下方法本质上也是使用的这个方法 |
Image.asset | 加载资源图片 |
Image.file | 加载本地图片文件 |
Image.network | 加载网络图片 |
Image.memory | 加载Uint8List资源图片 |
属性值
image
ImageProvider, 抽象类,需要自己实现获取图片数据的操作。如下是常用的一些ImageProvider,当然自定义自己的ImageProvider也是OK的,实现方法,可以参考下面表中这些已经成熟使用的例子。
ImageProvider |
---|
ExactAssetImage |
AssetImage |
NetworkImage |
FileImage |
MemoryImage |
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
appBar: new AppBar(title: new Text("Container Test"),
centerTitle: true,),
body: new ListView(
children: <Widget>[
// 资源图片
new Image.asset('imgs/logo.jpeg'),
//网络图片
new Image.network(
'https://flutter.io/images/homepage/header-illustration.png'),
// 本地文件图片
new Image.file(new File("/Users/gs/Downloads/1.jpeg")),
// Uint8List图片
new Image.memory(bytes),
//使用ImageProvider加载图片
new Image(image: new NetworkImage(
"https://flutter.io/images/homepage/screenshot-2.png"),)
],
),
);
}
width & height
Image显示区域的宽度和高度设置,这里需要把Image和图片两个东西区分开,图片本身有大小,Image Widget本身也是有大小的,Image Widget是图片的容器。宽度和高度的配置经常和下面的fit属性配合使用。
@override
Widget build(BuildContext context) {
// TODO: implement build
Image image = new Image.asset(
'imgs/logo.jpeg',
width: 200.0,
height: 100.0,
fit: BoxFit.fill,
);
return new Scaffold(
appBar: new AppBar(title: new Text("Image Test"),
centerTitle: true,),
body: image,
);
}
设置宽度高度,然后设置图片充满Image,因为我们的源图片是1:1的大小,所以这里拉伸或者挤压是正常。
fit
fit | Description | Result |
---|---|---|
BoxFit.fill | 全图显示,显示可能拉伸,充满 | |
BoxFit.contain | 全图显示,显示原比例,不需充满 | |
BoxFit.cover | 显示可能拉伸,可能裁剪,充满 | |
BoxFit.fitWidth | 显示可能拉伸,可能裁剪,宽度充满 | |
BoxFit.fitHeight | 显示可能拉伸,可能裁剪,高度充满 | |
BoxFit.none | ||
BoxFit.scaleDown | 效果和contain差不多,但是此属性不允许显示超过源图片大小,可小不可大 |
color & colorBlendMode
color和colorBlendMode一般配合使用,BlendMode, 为混合模式的意思,包含如下诸多模式。感觉和Android中Xfermode是一个原理。
随意看几个效果吧。
BlendMode.colorBurn
Image image = new Image.asset(
'imgs/logo.jpeg',
width: 400.0,
height: 500.0,
fit: BoxFit.scaleDown,
color: Colors.greenAccent,
colorBlendMode: BlendMode.colorBurn,
);
BlendMode.exclusion
BlendMode.colorDodge
alignment
控制图片的摆放位置。如下将图片放置在右下角。其他的位置自行尝试。
alignment: Alignment.bottomRight,
repeat
一图胜前言
Image image = new Image.asset(
'imgs/logo.jpeg',
width: 400.0,
height: 500.0,
fit: BoxFit.scaleDown,
repeat: ImageRepeat.repeat,
);
repeat | Results |
---|---|
ImageRepeat.repeat | |
ImageRepeat.repeatX | |
ImageRepeat.repeatY | |
ImageRepeat.none |
centerSlice
当图片需要被拉伸显示的时候,centerSlice定义的矩形区域会被拉伸,可以理解成我们在图片内部定义来一个点9文件用作拉伸。
Image image = new Image.asset(
'imgs/logo.jpeg',
width: 500.0,
height: 500.0,
fit: BoxFit.contain,
centerSlice: new Rect.fromCircle(center: const Offset(100.0, 100.0), radius: 10.0 ),
);
注意一下这部分,代码中有如是一段:
assert(sourceSize == inputSize, 'centerSlice was used with a BoxFit that does not guarantee that the image is fully visible.');
也就是说只有在显示大小大于原图大小的情况下,才允许使用这个属性,否则会报错。
matchTextDirection
与Directionality配合使用
@override
Widget build(BuildContext context) {
// TODO: implement build
Image image = new Image.asset(
'imgs/android.jpg',
fit: BoxFit.scaleDown,
matchTextDirection: true,
);
return new Scaffold(
appBar: new AppBar(title: new Text("Image Test"),
centerTitle: true,),
body: new ListView(
children: <Widget>[
new Directionality(
textDirection: TextDirection.ltr,
child: image,
),
new Directionality(
textDirection: TextDirection.rtl,
child: image,
),
],
)
);
}
列表中两个图片,第一个是TextDirection.ltr,第二个TextDirection.rtl。
gaplessPlayback
当ImageProvider发生变化后,重新加载图片的过程中,原图片的展示是否保留。若值为true,保留,若为false,不保留,直接空白等待下一张图片加载。
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
NetworkImage networkImage = new NetworkImage("https://flutter.io/images/homepage/header-illustration.png");
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
appBar: new AppBar(title: new Text("Image Test"),
centerTitle: true,),
body: new ListView(
children: <Widget>[
new Directionality(
textDirection: TextDirection.ltr,
child: new Image(image: widget.networkImage, fit: BoxFit.contain,gaplessPlayback: true,),
),
new InkWell(
child: new Text("点击我切换图片", textAlign: TextAlign.center,),
onTap: (){
setState(() {
print("change pic");
widget.networkImage = new NetworkImage("https://flutter.io/images/intellij/hot-reload.gif");
});
},)
],
)
);
}
}
gaplessPlayback | Result |
---|---|
true | |
false |