[番外]-Flutter小課堂-Image篇

前言

圖片是一個咱們又愛又恨的東西,它是萬美之本,也是萬惡之源
爲闡述清楚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組件對象的方法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, //經過內存建立
複製代碼

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的容器裏,表現效果以下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


2.2: 圖片的適應模式: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測試結果:

  • 圖片小於容器尺寸下的測試結果

根據圖片看一下,應該不言而喻了。佈局


2.3:顏色以及混合模式: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(),
);
複製代碼

若是之後有什麼須要類比的模式,枚舉什麼的,均可以經過這種方式批量生成,效果又好又省事。


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,期待與你的交流與切磋。

相關文章
相關標籤/搜索