精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

在 Flutter 中實現最佳 UX 性能的 12 個圖像技巧和最佳實踐

開發 前端
僅僅展示圖片是不夠的!您還應該為用戶提供他們需要的最佳體驗!因此,我強烈建議您創建自己的自定義圖片 widget,將它們隨意組合并自由使用!

Image widget 是 Flutter 中最常用的 widget 之一,但我相信我們沒有充分利用它的功能,僅僅顯示一個圖片是不夠的,你還應該給用戶他們需要的最佳體驗!

在這篇文章中,我將談論一些圖像技巧和最佳實踐,以獲得更好的性能和用戶體驗。

這些技巧是:

  • 1.使用 WebP 而不是 JPG/PNG
  • 2.設置寬度和高度以保留 UI 空間
  • 3.降低圖片的顯示分辨率以減少內存使用
  • 4.預加載/預緩存您的圖像,以便即時加載圖像
  • 5.加載時顯示進度指示器
  • 6.加載時顯示進度百分比指示器
  • 7.加載時顯示閃爍效果,以提高用戶體驗
  • 8.顯示 blurhash 作為占位符
  • 9.使用漸變效果來提高用戶體驗
  • 10.緩存圖像以減少網絡使用并提高性能
  • 11.注意非經常性成本
  • 12.在失敗時顯示重試按鈕
  • 結語

1.使用 WebP 而不是 JPG/PNG

WebP 是下一代圖像格式,它比 PNG 和 JPEG 小約 25%,并且比其他格式快。

這意味著,你的應用程序將使用更少的內存,構建速度更快。

這里有一些基準:

圖片圖片

圖片圖片

Image.asset(
  // 'image.jpg',
  'image.webp', // PREFER
);

2.設置寬度和高度以保留 UI 空間

它可以防止應用程序出現布局偏移

圖片圖片

之前——之后

Image.network(
  imageUrl,
  width: 200,
  height: 150,
);

3.降低圖片的顯示分辨率以減少內存使用

圖片圖片

圖片圖片

你的圖片可能會導致設備內存膨脹,這是因為,盡管它們在 UI 中占據相對較小的一部分,Flutter 還是會以全分辨率渲染它們,從而消耗大量內存。

為了避免這種問題,可以使用 cacheWidth 或 cacheHeight 參數對指定大小的圖像進行解碼。

此外,我們可以使用 Flutter 開發者工具輕松檢測超大圖像。

如果圖像過大,它會反轉圖像,使其顛倒。

注意!緩存大小不應該小于小部件的大小,否則,由于分辨率低,它看起來像素化!

Image.network(
  imageUrl,
  cacheWidth: 100,
  cacheHeight: 150,
);

4.預加載/預緩存您的圖像,以便即時加載圖像

如果你在顯示圖像之前緩存它們,Flutter 將跳過構建的處理步驟并立即顯示它們。

圖片圖片

class MyImage extends StatefulWidget {
  const MyImage({super.key});

  @override
  State createState() => _MyImageState();
}

class _MyImageState extends State {
  late final Image myImage;

  @override
  void initState() {
    super.initState();
    myImage = Image.asset('path');
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    precacheImage(myImage.image, context);
  }

  @override
  Widget build(BuildContext context) {
    return myImage;
  }
}

5.加載時顯示進度指示器

突然彈出圖像不是預期的行為,用戶可能會因為網絡連接不足而錯過圖像并向下滾動,或者可能在屏幕上看到一些空白,等等。我們應該始終通知用戶圖像正在加載。

圖片圖片

return Image.network(
  imageUrl,
  loadingBuilder: (_, child, event) {
    if (event == null) return child;
    return const Center(child: CircularProgressIndicator());
  },
);

6.加載時顯示進度百分比指示器

我們也可以顯示進度百分比,而不是無限加載,這樣對用戶來說更有用。

圖片圖片

return Image.network(
  imageUrl,
  loadingBuilder: (_, child, event) {
    if (event == null) return child;
    return Center(
      child: CircularProgressIndicator(
        value: event.cumulativeBytesLoaded / (event.expectedTotalBytes ?? 0),
      ),
    );
  },
);

7.加載時顯示閃爍效果,以提高用戶體驗

顯示進度條是好的,但并不是最好的選擇,顯示閃爍效果(Shimmer)要比顯示進度條好得多。

圖片圖片

return Image.network(
  imageUrl,
  height: 200,
  width: 350,
  loadingBuilder: (_, child, event) {
    if (event == null) return child;
    return const Shimmer(
      height: 200,
      width: 350,
     );
  }
);

// Most Basic Shimmer
class Shimmer extends StatefulWidget {
  const Shimmer({
    super.key,
    this.width,
    this.height,
    this.minOpacity = 0.015,
    this.maxOpacity = 0.15,
    this.borderRadius = const BorderRadius.all(Radius.circular(4)),
    this.child,
  });

  final double? width;
  final double? height;
  final double minOpacity;
  final double maxOpacity;
  final BorderRadius? borderRadius;
  final Widget? child;

  @override
  State createState() => _ShimmerState();
}

class _ShimmerState extends State with SingleTickerProviderStateMixin {
  late final AnimationController controller;

  @override
  void initState() {
    super.initState();
    controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 1),
      lowerBound: widget.minOpacity,
      upperBound: widget.maxOpacity,
    )..repeat(reverse: true);
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return RepaintBoundary(
      child: FadeTransition(
        opacity: controller,
        child: Container(
          width: widget.width,
          height: widget.height,
          decoration: BoxDecoration(
            color: Colors.black,
            borderRadius: widget.borderRadius,
          ),
          child: widget.child,
        ),
      ),
    );
  }
}

我創建了一個簡單的 shimmer 小部件,但你可以從官方文檔中學習如何創建高級版本的 shimmer 效果。

?

官方文檔:創建 shimmer 加載效果(https://docs.flutter.dev/cookbook/effects/shimmer-loading)

8.顯示 blurhash 作為占位符

為了改善用戶體驗,可以使用哈希代碼顯示圖像的模糊版本,而不是在圖像加載時顯示空白的灰色區域。

圖片圖片

https://blurha.sh/

return const SizedBox(
  width: 350,
  height: 200,
  child: BlurHash(
    hash: hashCode,
    imageFit: BoxFit.cover,
    image: imageUrl,
  ),
);

9.使用漸變效果來提高用戶體驗

默認情況下,圖片加載后立即顯示,這對我們的視覺體驗來說非常糟糕,為了改善這一點,我們可以用一個小的漸入動畫來顯示它們。

我們可以使用 FadeInImage 來實現這個功能。

它需要字節或資源作為占位符,在這個例子中,我將使用 transparent_image 包來獲取透明圖像字節。

我們還可以使用 cached_network_image 包來實現這一點,以及更多。

return FadeInImage.memoryNetwork(
  image: imageUrl,
  placeholder: kTransparentImage,
);

// 或者
return CachedNetworkImage(
  imageUrl: imageUrl,
);

10.緩存圖像以減少網絡使用并提高性能

為了避免每次下載相同的圖片,我們可以緩存第一次下載的圖片并重復使用,為了實現這一點,我們可以創建自己的緩存機制,或者我們可以直接使用 cached_network_image。

它緩存網絡圖像,默認情況下自動顯示它們的淡入效果,并提供了更多的圖像控制。

11.注意非經常性成本

Image widget 沒有 const 構造函數,雖然這在大多數情況下都不是問題,但我們可以通過將它包裝在自定義 widget 中來修復它。

它不僅可以讓我們的應用程序更具性能,而且我們還可以根據我們的意愿定制小部件,例如,我們可以為每個圖像小部件創建一個全局解決方案,而不是每次都處理 error/loading 情況。

enum _ImageType { asset, network }

class AppImage extends StatelessWidget {
  const AppImage.asset(
    this.image, {
    super.key,
  }) : type = _ImageType.asset;

  const AppImage.network(
    this.image, {
    super.key,
  }) : type = _ImageType.network;

  final String image;
  final _ImageType type;

  @override
  Widget build(BuildContext context) {
    const errorWidget = Icon(Icons.error);
    return switch (type) {
      _ImageType.asset => Image.asset(
          image,
          errorBuilder: (_, __, ___) => errorWidget,
        ),
      _ImageType.network => Image.network(
          image,
          errorBuilder: (_, __, ___) => errorWidget,
        ),
    };
  }
}


/// 使用
const AppImage.asset(''), // OK
const Image.asset(''), // 錯誤!!Image 沒有const構造函數

// 正如您所知,擁有 const 的小部件非常重要以獲得更好的性能。

12.在失敗時顯示重試按鈕

有時候由于網絡連接不好或其他原因,圖片無法第一次加載,顯示錯誤消息是好的,但這還不夠,如果我們想把應用的 UX 提升到另一個層次,我們應該讓用戶重新加載圖片,并繼續使用應用,而不會遇到任何麻煩。

圖片圖片

class MyImage extends StatefulWidget {
  const MyImage({super.key});

  @override
  State createState() => _MyImageState();
}

class _MyImageState extends State {
  int attempt = 0;

  @override
  Widget build(BuildContext context) {
    return CachedNetworkImage(
      imageUrl: imageUrl,
      cacheKey: '$attempt',
      height: 200,
      width: 250,
      fit: BoxFit.cover,
      errorWidget: (_, __, ___) {
        return RetryWidget(
          height: 200,
          width: 250,
          onTap: () => setState(() => attempt++),
        );
      },
    );
  }
}

// Just a basic retry button
class RetryWidget extends StatelessWidget {
  const RetryWidget({
    super.key,
    required this.height,
    required this.width,
    required this.onTap,
  });

  final double? height;
  final double? width;
  final void Function() onTap;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
        height: height,
        width: width,
        alignment: Alignment.center,
        decoration: const BoxDecoration(color: Colors.black12),
        child: const Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(Icons.image_not_supported, size: 20),
            SizedBox(height: 12),
            Padding(
              padding: EdgeInsets.symmetric(horizontal: 12),
              child: Text(
                "Image couldn't load, tap here to retry",
                textAlign: TextAlign.center,
                style: TextStyle(fontSize: 14, color: Colors.black),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

結語

僅僅展示圖片是不夠的!您還應該為用戶提供他們需要的最佳體驗!因此,我強烈建議您創建自己的自定義圖片 widget,將它們隨意組合并自由使用!

原文:https://medium.com/itnext/12-image-tips-and-best-practices-for-the-best-ux-performance-in-flutter-e7a1b2b1da2a&strip=0&vwsrc=1&referer=medium-parser

責任編輯:武曉燕 來源: 獨立開發者張張
相關推薦

2023-07-07 12:26:39

攜程開發

2023-09-13 08:00:00

JavaScript循環語句

2013-12-31 09:26:31

JavaScript技巧

2023-10-16 11:27:43

2011-08-11 09:45:25

2023-07-25 11:22:31

2010-02-04 11:55:27

ibmdwDB2

2012-03-29 09:35:32

WEBCSS

2012-03-19 09:55:38

CSS

2011-12-31 10:18:33

響應設計

2010-07-06 09:07:09

2009-11-26 10:31:55

配置IPS最佳實踐

2022-05-30 07:48:11

DevOps測試策略

2013-05-17 11:43:55

主數據數據管理

2010-11-15 09:13:22

云計算開發測試

2020-09-17 06:00:21

Git

2009-07-01 17:44:46

Servlet和JSP

2018-01-12 14:37:34

Java代碼實踐

2020-06-10 09:57:23

Kubernetes日志容器

2017-03-30 22:16:21

DevOpsIT應用程序
點贊
收藏

51CTO技術棧公眾號

欧美日韩成人精品| 欧美性xxxxxxxx| 97人人干人人| 一级aaa毛片| 精品国产乱码久久久久久蜜坠欲下| 欧美自拍丝袜亚洲| 中文字幕精品在线播放| 国模无码一区二区三区| 久久久久91| 欧美成人一区二区三区电影| 中国美女乱淫免费看视频| 成人在线黄色| 精品福利免费观看| 9l视频自拍9l视频自拍| 欧美熟妇精品黑人巨大一二三区| 日韩一级片在线免费观看| 日本另类视频| 五月婷婷色综合| 亚洲国产精品影视| 青青草免费在线视频| 国产一区二区不卡在线| 国产精品444| 中国一级免费毛片| 欧美一区视频| 色悠悠久久88| 亚洲第一成人网站| 黄色欧美网站| 欧美成人三级电影在线| 九色porny自拍| 在线精品亚洲欧美日韩国产| 一区二区在线看| 亚洲欧美日产图| 久久一级免费视频| 日韩一区二区视频在线| 激情五月综合网| 精品视频—区二区三区免费| 女王人厕视频2ⅴk| av日韩一区| 欧美视频在线不卡| 黄色一级免费大片| 在线视频超级| 欧美日韩精品在线视频| 成人短视频在线观看免费| 毛片在线视频| 国产精品久久久久久久久图文区| 欧美资源一区| 国模吧精品人体gogo| 99在线视频精品| 精品视频一区在线| 凸凹人妻人人澡人人添| 不卡的av电影在线观看| 成人一区在线看| 日本a级片电影一区二区| 激情综合网五月婷婷| 欧美a级在线| 欧美成人亚洲成人日韩成人| 手机av在线看| 欧美+日本+国产+在线a∨观看| 精品国产欧美一区二区五十路| 粉嫩精品久久99综合一区| 国产一区二区三区日韩精品| 在线播放国产一区中文字幕剧情欧美| 波多野结衣av在线观看| 亚洲人成精品久久久| 国产一区二区三区视频在线观看| 日本人亚洲人jjzzjjz| 大色综合视频网站在线播放| 色噜噜亚洲精品中文字幕| 国产精品69久久久久孕妇欧美| 日韩精品福利| 高清国产一区二区三区四区五区| 色综合久久久久综合| www.日日操| 国产三级一区| 欧美一激情一区二区三区| 欧美图片自拍偷拍| 开心激情综合| 国产一区二区精品丝袜| 啪啪一区二区三区| 欧美暴力喷水在线| 性色av香蕉一区二区| 在线永久看片免费的视频| 老色鬼精品视频在线观看播放| 成人欧美一区二区三区黑人孕妇| jizz国产视频| 2017欧美狠狠色| 一区二区三区国| 日韩成人伦理| 美女视频黄频大全不卡视频在线播放| 中文字幕巨乱亚洲| 久久亚洲午夜电影| 91大神在线网站| 亚洲综合激情小说| 日韩在线xxx| 中文成人在线| 亚洲国产欧美久久| 中文字幕精品亚洲| 亚洲一本视频| 国产欧美婷婷中文| 人人妻人人澡人人爽久久av | 成人av色在线观看| www.国产三级| 久久久国产精品午夜一区ai换脸| 亚洲av首页在线| 欧美7777| 欧美精品一区二区三区视频| 性少妇xx生活| 青娱乐91视频| 西野翔中文久久精品字幕| 揄拍成人国产精品视频| 国产在线观看成人| 久久爱另类一区二区小说| 国产中文一区二区| 在线视频中文字幕第一页| 91福利在线免费观看| 精品人妻人人做人人爽夜夜爽| 国产不卡av一区二区| 欧美激情国产高清| 国产男男gay体育生网站| 99r国产精品| 狠狠精品干练久久久无码中文字幕| 日韩精品专区| 亚洲国产成人在线播放| 午夜激情福利网| 秋霞成人午夜伦在线观看| 国产欧美精品一区二区三区| 高潮毛片在线观看| 五月综合久久| 日韩欧美资源站| 91禁男男在线观看| 天堂一区二区在线| 国内精品国语自产拍在线观看| 操你啦在线视频| 欧美亚洲高清一区二区三区不卡| 久久久午夜精品福利内容| 综合日韩在线| 92看片淫黄大片看国产片| 最新97超碰在线| 91国模大尺度私拍在线视频| 大又大又粗又硬又爽少妇毛片| 亚洲婷婷免费| 狠狠综合久久av| 爱啪啪综合导航| 精品久久国产老人久久综合| 在线免费观看亚洲视频| 国产麻豆视频一区二区| 久久免费视频2| 日韩精品一级毛片在线播放| 日韩精品一区二区三区免费观影 | 欧美午夜精品久久久久久人妖| 免费看91视频| 欧美色一级片| 懂色一区二区三区av片| 日韩伦理电影网站| 亚洲精品一区二区精华| 欧美不卡视频在线观看| 99re这里都是精品| www.欧美日本| 久久中文字幕二区| 91久久久在线| 欧美xxxx免费虐| 亚洲第一网中文字幕| 日韩男人的天堂| 久久毛片高清国产| 孩娇小videos精品| 中文视频一区| 国产综合色一区二区三区| 农村黄色一级片| 成人va天堂| 国产亚洲精品激情久久| 中文字幕一区二区三区人妻四季| 国产精品第四页| 欧美性受xxxx黒人xyx性爽| 欧美另类综合| 久久一区二区精品| 97欧美成人| 九九热视频这里只有精品| 欧美性受xxxx狂喷水| 欧美性20hd另类| 国精产品一区一区| 成人精品免费看| 欧美一级黄色影院| 欧美精品一区二区三区久久久竹菊| 国产九色精品| www.久久.com| 久久久久久com| 国产一区精品| 欧美成人女星排行榜| 中文在线第一页| 亚洲国产免费看| 亚洲三级小视频| 中文字幕永久视频| 欧美精品国产一区二区| 欧美lavv| 老司机亚洲精品一区二区| 午夜精品久久久久久久99黑人| yw193.com尤物在线| 日韩免费观看高清完整版在线观看| 久久久久久久黄色片| 亚洲欧洲精品一区二区三区不卡| 国产xxxxxxxxx| 久久国产精品99精品国产| 隔壁人妻偷人bd中字| 日韩久久精品网| 精品一区久久久| 国产高清精品二区| 国产ts一区二区| 免费男女羞羞的视频网站在线观看| 亚洲欧美日韩高清| 成人乱码一区二区三区| 欧美日韩亚洲综合| 一级做a爰片久久毛片| 日韩专区精品| 精品国产sm最大网站| 无码人妻精品一区二区三区9厂 | 99久久免费精品| 国产传媒免费观看| 日韩中文字幕麻豆| 日韩欧美视频网站| 欧美视频亚洲视频| 久久免费视频2| 日韩精品免费一区二区三区| 久久一区二区精品| 美女一区二区在线观看| 亚洲一区二区少妇| 亚洲美女色播| 国产精品旅馆在线| 亚洲wwww| 欧美影院在线播放| segui88久久综合| 欧美成人sm免费视频| 亚洲视频tv| 欧美韩国日本综合| 精品一区二区不卡| 秋霞影院一区| 5566中文字幕一区二区| 91国产一区| 国产有码在线一区二区视频| 欧洲成人一区| 国产91热爆ts人妖在线| 欧美专区福利免费| 欧美中文在线字幕| 天堂√中文最新版在线| 97视频在线观看播放| 亚洲天堂手机| 日本一区二区在线播放| 伊人久久综合一区二区| 青青精品视频播放| 日本免费久久| 国产成人一区二区三区小说| 亚洲成人激情社区| 国产精品天天狠天天看| 成人在线免费av| 成人h猎奇视频网站| 国产精品久一| 成人av蜜桃| 欧美男男freegayvideosroom| 欧美精品丝袜中出| 国产女女做受ⅹxx高潮| 欧美国产综合| 国产精品入口芒果| 久久激情视频| 五月婷婷六月丁香激情| 国产精品亚洲视频| 国产精品一区二区无码对白| 99久久精品99国产精品| 中文字幕在线1| 亚洲欧洲av一区二区三区久久| 成人在线观看小视频| 亚洲一区二区三区四区五区黄 | 婷婷国产在线综合| 国产乱码77777777| 欧美精品一级二级| 欧美在线 | 亚洲| 亚洲日本成人网| 欧美三级电影一区二区三区| 欧美成人精品在线观看| www.九色在线| 国产精品a久久久久久| 粉嫩av国产一区二区三区| 国产精品三区四区| 欧美日韩国产免费观看视频| 亚洲欧美日韩天堂| 大黑人交xxx极品hd| 国产喷白浆一区二区三区| 国产乱子轮xxx农村| 亚洲v精品v日韩v欧美v专区| www.日韩一区| 欧美第一区第二区| 岛国在线视频免费看| 久久99热精品这里久久精品| 三级在线看中文字幕完整版| 国产欧美日韩综合精品| 精品国产导航| 在线视频亚洲自拍| 亚洲尤物影院| 亚洲AV成人精品| 中文久久乱码一区二区| 国产91av视频| 精品视频在线免费看| 神马午夜电影一区二区三区在线观看| 中文字幕亚洲综合| 超级白嫩亚洲国产第一| 国产精品自产拍在线观看| 色婷婷狠狠五月综合天色拍| 中文精品一区二区三区| 亚洲综合电影一区二区三区| 香蕉视频在线观看黄| 欧美国产精品一区二区| 欧美日韩高清免费| 国产精久久一区二区| 欧美日韩一区二区三区在线视频| 午夜国产精品视频免费体验区| 韩国中文字幕av| 97aⅴ精品视频一二三区| 91免费公开视频| 欧美午夜片在线看| 亚洲三区在线播放| 国外成人性视频| 五月亚洲婷婷| 国产麻豆电影在线观看| 蜜桃一区二区三区在线观看| 国产传媒第一页| 婷婷激情综合网| 神马午夜电影一区二区三区在线观看 | 天堂在线视频观看| 久久97久久97精品免视看| 色成人综合网| 日韩三级电影网站| 亚洲欧美日韩视频二区| 好吊操视频这里只有精品| 亚洲欧美视频一区| 91精品视频免费在线观看| 国产一区二区日韩精品欧美精品| 三上悠亚影音先锋| 狠狠入ady亚洲精品经典电影| 亚洲欧美日韩综合网| 欧美国产成人精品| 精品乱码一区内射人妻无码| 国产亚洲欧美另类中文| 香蕉视频亚洲一级| 日本成人看片网址| 日本成人在线不卡视频| 欧美波霸videosex极品| 欧美亚洲国产一区二区三区| √天堂资源地址在线官网| 国产精品福利在线| 欧美午夜精彩| 成 人 黄 色 小说网站 s色| 国产精品色呦呦| 国产一区二区女内射| 久久精品国产99国产精品澳门| 亚洲精品aaa| 久久久国内精品| 波多野结衣一区二区三区| av黄色在线播放| 原创国产精品91| 久久免费福利| 日韩视频 中文字幕| www..com久久爱| 精品人妻一区二区色欲产成人| 亚洲一区二区久久久| 国产极品嫩模在线观看91精品| 综合视频在线观看| 国产欧美日韩精品一区二区三区| 日韩中文字在线| 成年人黄色大片在线| 久久精品中文字幕一区二区三区 | 99re6在线观看| 一区二区三区四区不卡视频| 天天综合天天综合| 国产成人黄色av| 亚洲精彩视频| 少妇一级淫免费观看 | 国产精品高潮呻吟久久久| 久久天天躁日日躁| 久久porn| 中文字幕 91| 亚洲国产成人av好男人在线观看| 色视频在线观看福利| 国产欧美日韩中文字幕在线| 欧美成人69| 成都免费高清电影| 91精品国产综合久久香蕉的特点| 96av在线| 吴梦梦av在线| 97se亚洲国产综合自在线观| 中文字幕在线一| 久久久久久久久中文字幕| 欧美热在线视频精品999| gogo亚洲国模私拍人体| 极品美女销魂一区二区三区免费| 91人成网站www| 888久久久| 欧美图片一区二区| 日韩欧美精品在线视频| 台湾成人免费视频| 国产中文字幕乱人伦在线观看| 欧美国产精品劲爆| 天天插天天干天天操|