盛年不重來,一日難再晨。及時宜自勉,歲月不待人。——陶淵明
最近着手用Flutter開發一個項目,以前因爲有原生開發的經驗,所以上手比較快。
應用開發的過程中不僅僅是編碼,還需要和UI小姐姐的配合,才能完成界面。如果要求我們手動去繪製一些圓形啊、線條啊、多邊形呀;這時就比較考驗你的耐心和基本功了。
看看UI給開發的設計圖,因爲沒有提供虛線切圖,這時需要我們手動去實現一下了,不辛苦,馬上就好。
思路
➊ 多個Container 相鄰拼湊,設置間距,同時和Colum\Row搭配,實現豎線或水平線
➋ 可以繪製一條水平的虛線,然後做一個旋轉90度,這樣不就是一條豎直的虛線了嗎
➌ 第三種方案就是我們今天要說的CustomPaint+畫布(Canvas) 進行實現
有人也許會疑惑,方案1和方案二不都是採用的繪製嗎,那可不一定。有的時候解決問題,我們不遵循常規也可以解決問題,滿足一時之需了。
1、解決問題奇葩方式一:
爲什麼奇葩呢?我們採用多個Container進行豎直或者水平排列完成了效果,至於性能上我們後面慢慢驗證了。
_lineContainer() {
return Container(
margin: EdgeInsets.only(top: 2.0),
color: Colors.blue,
height: 8.0,
width: 2.0,
);
}
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.white,
padding: EdgeInsets.only(top: 100.0),
child: Column(
children: <Widget>[
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
],
),
);
}
效果圖:
不同寬度的虛線只需要修改屬性width,達到效果。
水平虛線實現:
效果圖:
2、解決問題奇葩方式二:
多個Containter相鄰而且相同間距拼湊成水平線,然後進行一個旋轉:
_lineContainer() {
return Container(
alignment: Alignment.topLeft,
margin: EdgeInsets.only(left: 2.0),
color: Colors.green,
height: 2.0,
width: 8.0,
);
}
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.white,
alignment: Alignment.topLeft,
padding: EdgeInsets.only(top: 300.0),
child: DecoratedBox(
decoration: BoxDecoration(color: Colors.transparent),
child: Transform.rotate(
//旋轉90度
angle: math.pi / 2,
child: Row(
children: <Widget>[
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
_lineContainer(),
],
),
),
),
);
}
效果如下:
3、今天主要提及的CustomPaint+畫布(Canvas)
涉及的幾個點:畫筆(Paint)、樣式(PaintingStyle)、color(顏色)、線條寬度(strokeWidth);
offset(第一參數,第二參數):表示第一參數和第二參數之間的偏移量。
class MyPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
var paint = Paint()
..isAntiAlias = true
..style = PaintingStyle.fill //填充
..color = Color(0x77cdb175); //背景爲紙黃色
canvas.drawRect(Offset.zero & size, paint);
paint
..style = PaintingStyle.stroke //線
..color = Colors.red
..strokeWidth = 1.0;
for (int i = 0; i <= 35; ++i) {
double dx = 6.0 * i;
canvas.drawLine(Offset(dx, 20), Offset(dx, 22), paint);
}
}
//在實際場景中正確利用此回調可以避免重繪開銷,本示例我們簡單的返回true
@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
引用自定義繪畫:
@override
Widget build(BuildContext context) {
return Container(color: Colors.white,child :Center(
child: CustomPaint(
size: Size(300, 300), //指定畫布大小
painter: MyPainter(),
),
));
}
效果漸漸離我們很近了:
往後多餘的時間,我會對不同畫虛線的方式優缺點做對比。
總結:
不管我們用什麼方式繪製虛線,都可以達到同樣的效果;雖然有的方式很繁瑣,但是在解決問題的時候可以認爲它不是最佳選擇。努力去嘗試,儘量以Flutter官網作爲參考,這樣纔不會違背開發的原則。
參考:自繪組件 (CustomPaint與Canvas)https://book.flutterchina.club/chapter10/custom_paint.html
container:https://book.flutterchina.club/chapter5/container.html?h=Container
變換(transform):https://book.flutterchina.club/chapter5/transform.html?h=%E6%97%8B%E8%BD%AC