前言
圖片是一個我們又愛又恨的東西,它是萬美之本,也是萬惡之源
為闡述清楚Image的使用,專開本文,希望通過本文,你可以學到一個很有用的方法
另外通過最後佈局海賊王的懸賞令,基本實現可改頭像,名字,懸賞的效果,可縮放
1.Image的簡單認識
1.1: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;
複製程式碼
1.2.Image物件的建立
根據不同需求,一共有五種建立Image元件物件的方法
const Image({Key key,@required this.image,//通過ImageProvider建立
Image.network( String src, {//通過網路資源建立
Image.file(File file, { //通過檔案建立
Image.asset(String name, //通過資原始檔建立
Image.memory(Uint8List bytes, //通過記憶體建立
複製程式碼
1.3:資源圖片的訪問
在
Image.asset
中有一大段註釋介紹如何flutter中使用資源圖片
var img = Image.asset(
'images/icon_head.png',
width: 50,
height: 50,
);
複製程式碼
1.4:Image的狀態
Image是一個有狀態的元件,這點確實出乎我意料,我們看看他的狀態有哪些
class _ImageState extends State<Image> {
ImageStream _imageStream;
ImageInfo _imageInfo;
bool _isListeningToStream = false;
bool _invertColors;
複製程式碼
2.Image的屬性表現
2.1:Image的寬高
將3:2的圖片放在一個200*200的容器裡,表現效果如下
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元件佔據的佈局空間並非僅是圖片!
2.2: 圖片的適應模式:fit
為了方便對比,這裡寫了一個方法批量生成,可以看出各種模式的特性。
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測試結果
:
圖片小於容器尺寸下的測試結果
根據圖片看一下,應該不言而喻了。
2.3:顏色以及混合模式:color,colorBlendMode
同樣,也是批量測試一下,一圖勝千言,而且感覺高大上一點
這裡使用綠色和頭像進行疊合,效果如下:
//混合模式陣列
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(),
);
複製程式碼
如果以後有什麼需要類比的模式,列舉什麼的,都可以通過這種方式批量生成,效果又好又省事。
4. 對齊屬性: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(),
);
複製程式碼
2.5.重複模式: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(),
);
複製程式碼
1.5:縮放質量: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(),
);
複製程式碼
3.每日一佈局:海賊王懸賞令
暫時沒有抽成自定義元件。這裡不分析了,有興趣的小夥伴自己看看,也可以自定義個元件玩玩。
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
,期待與你的交流與切磋。