Flutter 剪裁組件的使用

效果展示

在實際項目當中我們經常看到如下各種剪裁形狀的效果,Flutter 為我們提供瞭非常方便的 Widget 很輕松就可以實現,下面我們來一起看看吧

剪裁 Widget

ClipRRect(圓角矩形剪裁)

這裡我們通過 borderRadius 屬性就可以很方便的設置圓角半徑來實現圓角剪裁

ClipRRect(
  borderRadius: BorderRadius.circular(20),
  child: Image.network(
    img1,
    height: height,
  ),
),

其他屬性

大概瞅一眼就可以看到 ClipRRect 的屬性就 5 個,這裡我們需要調整的可能就 1~3 個

  • borderRadius 圓角半徑
  • clipper 自定義圓角矩形剪裁
  • clipBehavior 剪裁方式
    • Clip.none 不剪裁
    • Clip.hardEdge 不進行抗鋸齒剪裁
    • Clip.antiAlias 默認-抗鋸齒剪裁
    • Clip.antiAliasWithSaveLayer 抗鋸齒並且合成層剪裁(這種模式不僅有抗鋸齒,還分配一個離屏緩存,後續的剪裁都在緩沖區進行)

其他形狀剪裁

這裡我們通過設置四個角的 borderRadius 可以達到不同的形狀效果,下面就具體來看看

葉子形狀

ClipRRect(
  borderRadius: BorderRadius.only(
    // 設置左下角半徑為 40
    bottomLeft: Radius.circular(40),
    // 設置右上角半徑為 40
    topRight: Radius.circular(40),
  ),
  child: ...,
),

“狗屋”形狀

ClipRRect(
  borderRadius: BorderRadius.vertical(
    // 設置頂部半徑為 40
    top: Radius.circular(40),
    // 設置低部半徑為 10
    bottom: Radius.circular(10),
  ),
  child: ...,
),

更多創意效果等你來發揮

ClipOval(橢圓剪裁)

如果你的子組件是長方形,那麼剪裁出來就是一個橢圓形

ClipOval(
  child: Image.network(
    img1,
    // 僅設置瞭高度,原始圖片是長方形
    height: height,
  ),
),

如果你的子組件是正方形,那麼剪裁出來就是一個圓形

// 定義的寬高相等
var width = 100.0;
var height = 100.0;

ClipOval(
  child: Image.network(
    img1,
    width: width,
    height: height,
    // 縮放
    fit: BoxFit.cover,
  ),
),

其他屬性

這裡隻有 clipper、clipBehavior ,與上面 ClipRRect 的屬性意思相同,不過多說明瞭

ClipRect(矩形剪裁)

這個很少用到,暫時沒有找到應用場景,就不過多說明瞭,你找到的話可以評論告訴我哦,我會及時更新上來的

ClipPath(路徑剪裁)

這個讓你發揮的自由度就更多瞭,比如 ⭐️五角星、❤️愛心、優惠券卡片 以及上面👆🏻所有的形狀都可以用路徑剪裁來實現,下面我們就實現一個底部曲線剪裁 的效果

ClipPath(
  // 這裡需要給 clipper 傳遞一個 CustomClipper<Path> 
  clipper: ClipperPath(),
  child: Image.network(
    img1,
    height: height,
  ),
),

這裡是創建曲線剪裁路徑,看瞭下面的代碼你就知道上面的其他剪裁 Widget 的 clipper 怎麼使用瞭

下面代碼註釋非常詳細,仔細看哦

/// 創建剪裁路徑
class ClipperPath extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    var path = Path();
    // 連接到距離左上角3/4處
    path.lineTo(0.0, size.height / 2);
    // 第一個控制點
    var firstControlPoint = Offset(0, size.height);
    // 目標點是底部中間點
    var firstPoint = Offset(size.width / 2, size.height);
    path.quadraticBezierTo(firstControlPoint.dx, firstControlPoint.dy,
        firstPoint.dx, firstPoint.dy);
    // 第二個控制點
    var secondControlPoint = Offset(size.width, size.height);
    // 目標點是右上角 3/4 處
    var secondPoint = Offset(size.width, size.height / 2);
    path.quadraticBezierTo(secondControlPoint.dx, secondControlPoint.dy,
        secondPoint.dx, secondPoint.dy);
    // 連接到右上角
    path.lineTo(size.width, 0.0);
    // 閉合
    path.close();
    // 返回剪裁路徑
    return path;
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) =>
      oldClipper.hashCode != this.hashCode;
}

Tips:剪裁路徑的開銷很大,對於某些形狀,建議選擇上面經過優化的 Widget 使用

做個優化

聰明的你一定發現,我們通過 ClipRRect 就可以實現這個效果,為啥還要寫這麼多代碼呢?來,看效果,上代碼

ClipRRect(
  borderRadius: BorderRadius.vertical(
    // 底部圓角半徑設置為 60
    bottom: Radius.circular(60),
  ),
  child: Image.network(
    img1,
    height: height,
  ),
),

源碼倉庫

基於 Flutter 🔥 最新版本

Flutter Widgets 倉庫

參考鏈接

ClipRRect (Flutter Widget of the Week)
Flutter-ClipRRect
Flutter-ClipRect
Flutter-ClipOval
Flutter-ClipPath
Flutter-CustomClipper

以上就是Flutter 剪裁組件的使用的詳細內容,更多關於Flutter 剪裁組件的資料請關註WalkonNet其它相關文章!

推薦閱讀: