Flutter學習筆記06-圖片

Flutter中薪前,可以通過Image組件來加載并顯示圖片,Image的數(shù)據(jù)源可以是asset柴淘、文件迫淹、內(nèi)存以及網(wǎng)絡(luò)秘通。

  • ImageProvider
    ImageProvider是一個抽象類,主要定義了圖片數(shù)據(jù)獲取的接口load()敛熬,從不同的數(shù)據(jù)源獲取圖片需要實現(xiàn)不同的ImageProvider 肺稀,如AssetImage是實現(xiàn)了從Asset中加載圖片的ImageProvider,而NetworkImage實現(xiàn)了從網(wǎng)絡(luò)加載圖片的ImageProvider应民』霸可以自行查閱文檔ImageProvider

1.從asset中加載圖片

在工程根目錄下創(chuàng)建一個文件夾,并將圖片拷貝到文件夾诲锹。在pubspec.yaml中的flutter部分添加如下內(nèi)容:

  assets:
    - assets/images/avatar.png

然后執(zhí)行flutter pub get繁仁。
ps:yaml文件對縮進嚴格,所以必須嚴格按照每一層兩個空格的方式進行縮進归园,此處assets前面應(yīng)有兩個空格黄虱。筆者習慣創(chuàng)建兩層文件夾assets放圖片資源、字體資源等庸诱,images專門放圖片資源捻浦,所以在pubspec.yaml中配置assets/images/avatar.png
加載圖片代碼示例如下:

class AssetImageDefault1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Image(
      image: AssetImage('assets/images/avatar.png'),
      width: 200,
      height: 200,
      alignment: Alignment.center,
    );
  }
}

Image也提供了一個快捷的構(gòu)造函數(shù)Image.asset用于顯示圖片,代碼示例如下:

class ImageAssetDefault2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Image.asset(
      'assets/images/avatar.png',
      width: 200,
      height: 200,
      alignment: Alignment.center,
    );
  }
}

運行上面兩個示例桥爽,效果圖如下:

如果加載時報錯找不到圖片資源朱灿,有可能是兩個原因:
1.pubspec.yaml中書寫不規(guī)范。不規(guī)范的縮進和字符都可能導致配置的內(nèi)容不生效钠四。要注意yaml的一個縮進是2個空格盗扒。如下圖所示:

asset配置

2.代碼中的圖片相對路徑要和工程中實際路徑不一致。例如:項目flutter_demo/assets/images/demo.png形导,引用路徑:AssetImage('assets/images/demo.png')

2.從網(wǎng)絡(luò)加載圖片

代碼示例如下:

class ImageNetWorkDefault1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Image(
      image: NetworkImage(
          'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg'),
      width: 200,
      height: 200,
      alignment: Alignment.center,
    );
  }
}

Image也提供了一個快捷的構(gòu)造函數(shù)Image.network用于加載網(wǎng)絡(luò)圖片,代碼示例如下:

class ImageNetWorkDefault2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Image.network(
      'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg',
      width: 200,
      height: 200,
    );
  }
}

代碼運行效果圖如下:

3.參數(shù)

Image在顯示圖片時定義了一系列參數(shù)习霹,通過這些參數(shù)可以控制圖片的顯示外觀朵耕、大小、混合效果等淋叶。Image的主要參數(shù)如下:

const Image({
  ...
  this.width, // 圖片的寬
  this.height, // 圖片高度
  this.color, // 圖片的混合色值
  this.colorBlendMode, // 混合模式
  this.fit,// 縮放模式
  this.alignment = Alignment.center, // 對齊方式
  this.repeat = ImageRepeat.noRepeat, // 重復方式
  ...
})
  • width height
    用于設(shè)置圖片的寬阎曹、高,當不指定寬高時煞檩,圖片會根據(jù)當前父容器的限制处嫌,盡可能的顯示其原始大小,如果只設(shè)置width斟湃、height的其中一個熏迹,那么另一個屬性默認會按比例縮放,可以通過fit屬性來指定適應(yīng)規(guī)則凝赛。
  • fit
    該屬性用于在圖片的顯示空間和圖片本身大小不同時指定圖片的適應(yīng)模式注暗。適應(yīng)模式是在BoxFit中定義坛缕,它是一個枚舉類型,有如下值:
    fill:會拉伸填充滿顯示空間捆昏,圖片本身長寬比會發(fā)生變化,圖片會變形。
    cover:會按圖片的長寬比放大后居中填滿顯示空間归形,圖片不會變形震庭,超出顯示空間部分會被剪裁。
    contain:圖片的默認適應(yīng)規(guī)則寇仓,圖片會在保證圖片本身長寬比不變的情況下縮放以適應(yīng)當前顯示空間举户,圖片不會變形。
    fitWidth:圖片的寬度會縮放到顯示空間的寬度焚刺,高度會按比例縮放敛摘,然后居中顯示,圖片不會變形乳愉,超出顯示空間部分會被剪裁兄淫。
    fitHeight:圖片的高度會縮放到顯示空間的高度,寬度會按比例縮放蔓姚,然后居中顯示捕虽,圖片不會變形,超出顯示空間部分會被剪裁坡脐。
    none:圖片沒有適應(yīng)策略泄私,會在顯示空間內(nèi)顯示圖片,如果圖片比顯示空間大备闲,則顯示空間只會顯示圖片中間部分晌端。
    下面例子是對一個寬高相同的圖片應(yīng)用不同的fit值,代碼示例如下:
class FitImageDemo extends StatelessWidget {
  final imageName = 'assets/images/avatar.png';

  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: Column(
        children: <Image>[
          Image.asset(
            imageName,
            height: 50,
            width: 50,
            fit: BoxFit.fill,
          ),
          Image.asset(
            imageName,
            height: 50,
            width: 50,
            fit: BoxFit.contain,
          ),
          Image.asset(
            imageName,
            width: 100,
            height: 50,
            fit: BoxFit.cover,
          ),
          Image.asset(
            imageName,
            width: 100,
            height: 50,
            fit: BoxFit.fitWidth,
          ),
          Image.asset(
            imageName,
            width: 100,
            height: 50,
            fit: BoxFit.fitHeight,
          ),
          Image.asset(
            imageName,
            width: 100,
            height: 50,
            fit: BoxFit.scaleDown,
          ),
          Image.asset(
            imageName,
            width: 100,
            height: 50,
            fit: BoxFit.none,
          ),
        ].map((e) {
          return Row(
            children: <Widget>[
              Padding(
                padding: EdgeInsets.all(16.0),
                child: SizedBox(
                  width: 100,
                  child: e,
                ),
              ),
              Text(e.fit.toString()),
            ],
          );
        }).toList(),
      ),
    );
  }
}

代碼運行效果圖如下:
  • color colorBlendMode
    在圖片繪制時可以對每一個像素進行顏色混合處理恬砂,color指定混合色咧纠,colorBlendMode指定混合模式,代碼示例:
Image.asset(
  'assets/images/avatar.png',
  width: 100,
  color: Colors.blue,
  colorBlendMode: BlendMode.difference,
),

運行效果如下:
  • repeat
    當圖片本身大小小于顯示空間時泻骤,指定圖片的重復規(guī)則漆羔。代碼示例如下:
Image.asset(
  'assets/images/avatar.png',
  width: 100,
  height: 200,
  repeat: ImageRepeat.repeatY,
),

代碼運行效果圖如下:

4.實現(xiàn)圓角圖像

實現(xiàn)圓角圖像有多種方式。

  • CircleAvatar
    CircleAvatar可以實現(xiàn)圓角頭像狱掂,也可以添加一個子Widget演痒。源碼如下:
const CircleAvatar({
  Key key,
  this.child, // 子Widget
  this.backgroundColor, // 背景顏色
  this.backgroundImage, // 背景圖像
  this.foregroundColor, // 前景顏色
  this.radius, // 半徑
  this.minRadius, // 最小半徑
  this.maxRadius, // 最大半徑
})

代碼示例如下:

class CircleAvatarImage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CircleAvatar(
      radius: 100,
      backgroundImage: NetworkImage(
          'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg'),
      child: Container(
        alignment: Alignment.center,
        width: 100,
        height: 100,
        child: Text('貓頭鷹'),
      ),
    );
  }
}

運行效果圖如下:
  • ClipOval
    ClipOval也可以實現(xiàn)圓角頭像,通常是在只有頭像時使用趋惨。代碼示例如下:
class ClipOvalImage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ClipOval(
      child: Image.network(
        'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg',
        width: 100,
        height: 100,
      ),
    );
  }
}

運行效果圖如下:
  • ClipRRect
    ClipRRect用于實現(xiàn)圓角效果鸟顺,可以設(shè)置圓角的大小。代碼示例如下:
class ClipRRectImage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: BorderRadius.circular(20),
      child: Image.network(
        'https://tva1.sinaimg.cn/large/006y8mN6gy1g7aa03bmfpj3069069mx8.jpg',
        width: 100,
        height: 100,
      ),
    );
  }
}

運行效果圖如下:

5.加載網(wǎng)絡(luò)圖片時顯示占位圖

加載網(wǎng)絡(luò)圖片時顯示占位圖可以用FadeInImage器虾,部分源碼如下:

 const FadeInImage({
    @required this.placeholder,
    @required this.image,
    this.fadeOutDuration = const Duration(milliseconds: 300),
    this.fadeInDuration = const Duration(milliseconds: 700),
    this.width,
    this.height,
    ...
  })
 /// Image displayed while the target [image] is loading.
  final ImageProvider placeholder;

  /// The target image that is displayed once it has loaded.
  final ImageProvider image;
  • placeholder
    默認顯示的占位圖
  • image
    真正顯示的圖片
  • fadeOutDuration fadeOutDuration
    placeholder消失image顯示的過程有一個淡進淡出诊沪,fadeOutDuration和fadeOutDuration就是設(shè)置淡進淡出的時間养筒,不想那個要這種效果將Duration設(shè)置1毫秒,不可以設(shè)置為0端姚。

代碼示例如下:

class FadeImageDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: FadeInImage(
        placeholder: AssetImage('assets/images/avatar.png'),
        image: NetworkImage(
            'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl-2.jpg'),
        fadeInDuration: Duration(milliseconds: 1),
        fadeOutDuration: Duration(milliseconds: 1),
        width: 200,
        height: 200,
      ),
    );
  }
}

但是這種方法沒有緩存每次都需要一段時間加載網(wǎng)絡(luò)圖片晕粪,cached_network_image 這個庫實現(xiàn)了圖片緩存加載和占位圖效果,可自行查閱文檔渐裸。

代碼傳送門

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末巫湘,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子昏鹃,更是在濱河造成了極大的恐慌尚氛,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件洞渤,死亡現(xiàn)場離奇詭異阅嘶,居然都是意外死亡,警方通過查閱死者的電腦和手機载迄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門讯柔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人护昧,你說我怎么就攤上這事魂迄。” “怎么了惋耙?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵捣炬,是天一觀的道長。 經(jīng)常有香客問我绽榛,道長湿酸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任灭美,我火速辦了婚禮推溃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘冲粤。我一直安慰自己美莫,他們只是感情好页眯,可當我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布梯捕。 她就那樣靜靜地躺著,像睡著了一般窝撵。 火紅的嫁衣襯著肌膚如雪傀顾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天碌奉,我揣著相機與錄音短曾,去河邊找鬼寒砖。 笑死,一個胖子當著我的面吹牛嫉拐,可吹牛的內(nèi)容都是我干的哩都。 我是一名探鬼主播,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼婉徘,長吁一口氣:“原來是場噩夢啊……” “哼漠嵌!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起盖呼,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤儒鹿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后几晤,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體约炎,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年蟹瘾,在試婚紗的時候發(fā)現(xiàn)自己被綠了圾浅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡热芹,死狀恐怖贱傀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情伊脓,我是刑警寧澤府寒,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站报腔,受9級特大地震影響株搔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜纯蛾,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一纤房、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧翻诉,春花似錦炮姨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至芦圾,卻和暖如春蛾派,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工洪乍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留眯杏,地道東北人。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓壳澳,卻偏偏與公主長得像岂贩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子巷波,可洞房花燭夜當晚...
    茶點故事閱讀 42,925評論 2 344