圖片是一個咱們又愛又恨的東西,它是萬美之本,也是萬惡之源
爲闡述清楚Image的使用,專開本文,但願經過本文,你能夠學到一個頗有用的方法
另外經過最後佈局海賊王的懸賞令,基本實現可改頭像,名字,懸賞的效果,可縮放算法
首先Image做爲組件存在於
widgets/image.dart
,dart.ui裏也有個Image類,別導錯了
其次,Image做爲一個有狀態的組件,繼承自StatefulWidget ,全部屬性以下:數組
class Image extends StatefulWidget {
const Image({
Key key,
@required this.image,
this.semanticLabel,//語義標籤
this.excludeFromSemantics = false,
this.width,//寬
this.height,/高
this.color,//顏色
this.colorBlendMode,//顏色混合模式
this.fit,//圖片適應模式
this.alignment = Alignment.center,//對齊
this.repeat = ImageRepeat.noRepeat,//重複
this.centerSlice,
this.matchTextDirection = false,
this.gaplessPlayback = false,
this.filterQuality = FilterQuality.low,//濾鏡質量
}) : assert(image != null),
assert(alignment != null),
assert(repeat != null),
assert(filterQuality != null),
assert(matchTextDirection != null),
super(key: key);
final ImageProvider image;
final double width;
final Color color;
final BlendMode colorBlendMode;
final BoxFit fit;
final AlignmentGeometry alignment;
final ImageRepeat repeat;
final Rect centerSlice;
final bool matchTextDirection;
final bool gaplessPlayback;
final String semanticLabel;
final bool excludeFromSemantics;
複製代碼
根據不一樣需求,一共有五種建立Image組件對象的方法bash
const Image({Key key,@required this.image,//經過ImageProvider建立
Image.network( String src, {//經過網絡資源建立
Image.file(File file, { //經過文件建立
Image.asset(String name, //經過資源文件建立
Image.memory(Uint8List bytes, //經過內存建立
複製代碼
在
Image.asset
中有一大段註釋介紹如何flutter中使用資源圖片微信
var img = Image.asset(
'images/icon_head.png',
width: 50,
height: 50,
);
複製代碼
Image是一個有狀態的組件,這點確實出乎我意料,咱們看看他的狀態有哪些網絡
class _ImageState extends State<Image> {
ImageStream _imageStream;
ImageInfo _imageInfo;
bool _isListeningToStream = false;
bool _invertColors;
複製代碼
將3:2的圖片放在一個200*200的容器裏,表現效果以下less
var img = Image.asset(
'images/ls.jpg',
width: 100,
height: 100,
);
var imgContainer=Container(
width: 200,
height: 200,
color: Colors.cyanAccent,
child: img,
);
複製代碼
其中能夠看出:
1.默認狀況下圖像會顯示徹底
2.這裏Container定義的長寬,可見Image的長寬是無效的
3.Image組件佔據的佈局空間並不是僅是圖片!dom
fit
爲了方便對比,這裏寫了一個方法批量生成,能夠看出各類模式的特性。ide
var fitMode = [BoxFit.none, BoxFit.contain, BoxFit.cover,
BoxFit.fill, BoxFit.fitHeight, BoxFit.fitWidth, BoxFit.scaleDown
];
//循環生成Image控件
form() {
var imgLi = <Widget>[];
fitMode.forEach((fit) {
var img = Container(
margin: EdgeInsets.all(10),
width: 150,
height: 60,
color: randomRGB(),
child: Image(
image: AssetImage("images/ls.jpg"),
fit: fit,
));
imgLi.add(Column(
children: <Widget>[img, Text(fit.toString())],
));
});
return imgLi;
}
var imgBox = Wrap(
children: form(),
);
Color randomRGB() {
Random random = new Random();
int r = 30 + random.nextInt(200);
int g = 30 + random.nextInt(200);
int b = 30 + random.nextInt(200);
return Color.fromARGB(255, r, g, b);
}
複製代碼
寬高比2:3測試結果
:寬高比3:2測試結果
:圖片小於容器尺寸下的測試結果
根據圖片看一下,應該不言而喻了。佈局
color,colorBlendMode
一樣,也是批量測試一下,一圖勝千言,並且感受高大上一點
這裏使用綠色和頭像進行疊合,效果以下:post
//混合模式數組
var colorBlendMode = [
BlendMode.clear,BlendMode.src,BlendMode.dst,
BlendMode.srcOver,BlendMode.dstOver,BlendMode.srcIn,
BlendMode.dstIn,BlendMode.srcOut,BlendMode.dstOut,
BlendMode.srcATop,BlendMode.dstATop,BlendMode.xor,
BlendMode.plus, BlendMode.modulate,BlendMode.screen,
BlendMode.overlay,BlendMode.darken,BlendMode.lighten,
BlendMode.colorDodge,BlendMode.colorBurn,BlendMode.hardLight,
BlendMode.softLight,BlendMode.difference,BlendMode.exclusion,
BlendMode.multiply,BlendMode.hue,BlendMode.saturation,
BlendMode.color, BlendMode.luminosity,
];
//循環生成Image控件
formImgsColorBlendMode() {
var imgLi = <Widget>[];
colorBlendMode.forEach((mode) {
var img = Container(
margin: EdgeInsets.all(5),
width:60,
height: 60,
child: Image(
image: AssetImage("images/icon_head.png"),
color: Colors.blue,
colorBlendMode: mode,
));
imgLi.add(Column(children: <Widget>[
img,
Text(mode.toString().split(".")[1])
]));
});
return imgLi;
}
var imageColorMode = Wrap(
children: formImgsColorBlendMode(),
);
複製代碼
若是之後有什麼須要類比的模式,枚舉什麼的,均可以經過這種方式批量生成,效果又好又省事。
alignment
有9個靜態常量,分別是九個方位,另外也能夠經過Alignment的構造方法來進行對齊偏移
var alignments = [
Alignment.center, Alignment.centerLeft, Alignment.centerRight,
Alignment.topCenter,Alignment.topLeft, Alignment.topRight,
Alignment.bottomCenter,Alignment.bottomLeft,Alignment.bottomRight,
Alignment(0.01,0.01),Alignment(0.5,0.5)
];
//循環生成Image控件
formImgAlignments() {
var imgLi = <Widget>[];
alignments.forEach((align) {
var img = Container(
margin: EdgeInsets.all(7),
width: 150,
height: 60,
color: randomRGB(),
child: Image(
image: AssetImage("images/wy_300x200_little.jpg"),
alignment: align,
));
imgLi.add(Column(
children: <Widget>[img, Text(e.toString())],
));
});
return imgLi;
}
var imageAlignments = Wrap(
children: formImgAlignments(),
);
複製代碼
repeat
一目瞭然,很少說
var repeats = [
ImageRepeat.repeatY, ImageRepeat.repeatX,
ImageRepeat.noRepeat,ImageRepeat.repeat
];
//循環生成Image控件
formImgRepeat() {
var imgLi = <Widget>[];
repeats.forEach((repeat) {
var img = Container(
margin: EdgeInsets.all(7),
width: 150,
height: 90,
color: randomRGB(),
child: Image(
image: AssetImage("images/wy_300x200_little.jpg"),
repeat: repeat,
));
imgLi.add(Column(
children: <Widget>[img, Text(repeat.toString())],
));
});
return imgLi;
}
var imageRepeats = Wrap(
children: formImgRepeat(),
);
複製代碼
filterQuality
源碼上說: 使用
FilterQuality.low
在縮放圖片時使用二次線性插值算法
FilterQuality.none
在縮放圖片時使用臨近算法
FilterQuality.hight
是最好的,也是最慢的,一般是三次插值或更好
FilterQuality.medium
的速度介於low和hight之間,一般是二次線性插值和錐體參數預濾波(mipmaps)的結合。
講得挺高大上,但用起來感受也就那回事,hight確實要比none感受好
var qualitys = [
FilterQuality.none,FilterQuality.high,
FilterQuality.medium, FilterQuality.low,
];
//循環生成Image控件
formImgQualitys() {
var imgLi = <Widget>[];
qualitys.forEach((q) {
var img = Container(
margin: EdgeInsets.all(7),
width:110.0*3/2,
height: 110,
color: randomRGB(),
child: Image(
image: AssetImage("images/wy_300x200.jpg"),
filterQuality: q,
));
imgLi.add(Column(
children: <Widget>[img, Text(q.toString())],
));
});
return imgLi;
}
var imageQualitys = Wrap(
children: formImgQualitys(),
);
複製代碼
暫時沒有抽成自定義組件。這裏不分析了,有興趣的小夥伴本身看看,也能夠自定義個組件玩玩。
const double viewRate = 0.663306; //視圖寬高比
const double imgRate = 1.234411;//圖片寬高比
var width =300.0;
double height = width/viewRate;
var textWanted= Text('WANTED',
style: TextStyle(
fontWeight: FontWeight.bold,
letterSpacing:width/30,
fontSize: width/6),
);
var name =Text('NA MI',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: width/9),
);
var price= Text('16,000,000',
style: TextStyle(
letterSpacing:width/45,
fontWeight: FontWeight.bold,
fontSize: width/10),
);
var img =Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black,width: width/100),
),
width: width,
height: width/imgRate,
child: Image.asset('images/娜美.jpg',fit: BoxFit.cover,),
);
var bottom =Stack(
children: <Widget>[
Image.asset('images/bottom.jpg',fit: BoxFit.fitWidth,),
Container(child: name,alignment: Alignment.topCenter,padding: EdgeInsets.only(top: 6*width/100),),
Container(child: price,alignment: Alignment.topCenter,padding: EdgeInsets.only(top: 17*width/100),)
],);
var wanted = Container(
width: width,
height: height,
color: Color(0xffded0b5),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[textWanted,Padding(padding:
EdgeInsets.fromLTRB(5*width/100,0,5*width/100,5*width/100),child: img,),
bottom
],),
);
var result=Card(child:wanted ,elevation: 5*width/100,);//最終組件
複製代碼
本文到此接近尾聲了,若是想快速嚐鮮Flutter,《Flutter七日》會是你的必備佳品;若是想細細探究它,那就跟隨個人腳步,完成一次Flutter之旅。
另外本人有一個Flutter微信交流羣,歡迎小夥伴加入,共同探討Flutter的問題,本人微信號:zdl1994328
,期待與你的交流與切磋。