Flutter實戰之畫布使用篇

自定義樣式

最近Flutter項目新需求中須要實現圓弧樣式,以下圖所示:html

在Flutter自身UI組件中好像也沒有直接可用圓弧並帶缺口的組件。因此圓弧樣式就須要本身自定義繪製了。 在Flutter中一樣也有畫布功能用於開發者繪製自定義樣式。

畫布

畫布組件CustomPaint,繪製內容經過painter和foregroundPainter。painter繪製在child以前,foregroundPainter繪製在child以後,所以child內容覆蓋在painter上層,foregroundPainter內容覆蓋在child上層。前端

CustomPaint(
  painter: CanvasPainter(),
  foregroundPainter: ForegroundPainter(),
  child: Container(
      height: 50,
      decoration: BoxDecoration(
        border: Border.all(color: Colors.black, width: 5),
      ),
      child: Text("我是CustomPaint的child"),
  ),
),
複製代碼

繪製

繪製部分的實現由CustomPainter完成。首先建立一個繼承CustomPainter的類對象。git

  • paint方法經過canvas繪製內容,size獲取canvas大小。
  • shouldRepaint判斷是否須要重繪。
class DemoPainter extends CustomPainter{
  @override
  void paint(Canvas canvas, Size size) {
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return null;
  }
}
複製代碼

圓弧計算

1度 = pi / 180,因此起始度數 = 度數 * pi / 180。github

drawArc方法0度位置是在圓點水平位置左側正方向是順時針,因此圓弧繪製第一個起始度數參數爲-240度(-240 * (pi / 180)),已知0度位置並知道360度位置。-240度位置距離圓點垂直位置下方度數爲30,缺口總共度數爲60。所以第二個度數參數爲 300 * (pi / 180)。canvas

圓弧實現

繪製圓弧使用drawArc方法,設置繪製圓形尺寸(圓心,半徑)、起始角度、圓弧角度、是否閉合。bash

@override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint();
    paint.style = PaintingStyle.stroke;
    paint.strokeWidth = 5;
    paint.strokeCap = StrokeCap.round;
    paint.color = Colors.white;
    canvas.drawArc(
        Rect.fromCircle(
            center: Offset(size.width / 2, size.height / 2), radius: 70),
        -240 * (pi / 180),
        300 * (pi / 180),
        false,
        paint);
    paint.strokeWidth = 2;
    canvas.drawArc(
        Rect.fromCircle(
            center: Offset(size.width / 2, size.height / 2), radius: 65),
        -240 * (pi / 180),
        300 * (pi / 180),
        false,
        paint);
    paint.strokeWidth = 1;
    canvas.drawArc(
        Rect.fromCircle(
            center: Offset(size.width / 2, size.height / 2), radius: 60),
        -240 * (pi / 180),
        300 * (pi / 180),
        false,
        paint);
  }

複製代碼

另外CustomPainter還有child,能夠經過Stack將文本內容經過Text居中顯示,固然UI中間文本和按鈕固然也能夠用畫布繪製的方式實現,完整畫布代碼以下:ide

DemoPainter(
   painter: CanvasPainter(),
   foregroundPainter: ForegroundPainter(),
   child: Container(
     height: 50,
     decoration: BoxDecoration(
       border: Border.all(color: Colors.black, width: 5),
     ),
     child: Stack(
       children: <Widget>[
         Text("我是CustomPaint的child"),
         Center(
           child: Text(
             "96",
             style: TextStyle(
               color: Colors.white,
               fontSize: 30,
               fontWeight: FontWeight.bold,
             ),
           ),
         )
       ],
     ),
   ),
 ),
複製代碼

最終效果

這只是比較簡單的畫布應用,能夠用畫布繪製圖片、根據數學公式繪製更多圖形、文字和其餘絢麗自定義樣式。Canvas在無論是在前端、客戶端都是會有相似的使用場景,並且接觸多了以後會發現每一個語言上封裝的接口和方法都很類似,由於在作Android開發的時候也接觸過確實是大同小異,因此畫布其餘具體功能再也不展開。

最後的最後介紹兩個優秀的Flutter圖表開源庫Syncfusion Flutter ChartsFlutter Charting 。你會驚喜的發現經過畫布實現圖表功能原來能夠這麼酷炫。ui

Demo代碼地址

參考

相關文章
相關標籤/搜索