Flutter自定義繪制組件

Flutter中自定義組件一般有兩種方式:

  • 通過已有widget進(jìn)行組合
  • 通過CustomPaint進(jìn)行繪制
    下面主要介紹下CustomPaint繪制方式。

1. 認(rèn)識(shí)CustomPaint

CustomPaint繼承自SingleChildRenderObjectWidget,即它可以在通過嵌套引入到widget樹中躲叼,并且可以有一個(gè)child子widget蛙酪。它的構(gòu)造方法如下:

const CustomPaint({
    Key key,
    this.painter,
    this.foregroundPainter,
    this.size = Size.zero,
    this.isComplex = false,
    this.willChange = false,
    Widget child,
  }) : assert(size != null),
       assert(isComplex != null),
       assert(willChange != null),
       super(key: key, child: child);

painter和foregroundPainter需要接收CustomPainter對(duì)象促脉,是CustomPaint核心助币。CustomPainter是進(jìn)行UI繪制的核心類猴蹂,繪制時(shí), CustomPaint 首先在畫布上調(diào)用 painter繪制 , 然后再繪制它的 child Widget, child 繪制完成后再調(diào)用 foregroundPainter 進(jìn)行繪制蓬网。
size屬性標(biāo)識(shí)繪制區(qū)域大小窒所,但當(dāng)CustomPaint有child,該屬性將會(huì)忽略帆锋,而使用child的大小為繪制區(qū)域大小吵取。
isComplex和willChange用于控制繪制層緩存處理的,這里暫不討論锯厢。

2. CustomPainter

可實(shí)現(xiàn)CustomPainter子類進(jìn)行UI繪制

void paint(Canvas canvas, Size size);

實(shí)現(xiàn)paint方法進(jìn)行真正的繪制皮官,canvas是畫布對(duì)象,size是繪制區(qū)域实辑,是從CustomPaint中size屬性傳遞得到的捺氢。繪制過程與Android原生開發(fā)十分類似,連API都十分相像剪撬,這點(diǎn)對(duì)熟悉Android原生開發(fā)者真是太友好了摄乒。

2.1 Paint

Paint對(duì)象是畫筆對(duì)象,就是繪圖工具残黑,我們可以設(shè)置畫筆的顏色缺狠、粗細(xì)、是否抗鋸齒萍摊、筆觸形狀以及作畫風(fēng)格等,通過這些屬性我們可以很方便的來定制自己的UI效果如叼,在繪制的過程中可以定義多個(gè)畫筆冰木,以便實(shí)現(xiàn)多種風(fēng)格圖形的集合。

Paint _paint = Paint()
    ..color = Colors.pink //畫筆顏色
    ..strokeCap = StrokeCap.round //畫筆筆觸類型
    ..isAntiAlias = true //是否啟動(dòng)抗鋸齒
    ..blendMode = BlendMode.exclusion //顏色混合模式
    ..style = PaintingStyle.fill //繪畫風(fēng)格笼恰,默認(rèn)為填充
    ..colorFilter = ColorFilter.mode(Colors.blueAccent,
        BlendMode.exclusion) //顏色渲染模式踊沸,一般是矩陣效果來改變的,但是flutter中只能使用顏色混合模式
    ..maskFilter = MaskFilter.blur(BlurStyle.inner, 3.0) //模糊遮罩效果,flutter中只有這個(gè)
    ..filterQuality = FilterQuality.high //顏色渲染模式的質(zhì)量
    ..strokeWidth = 15.0; //畫筆的寬度

根據(jù)需求選擇合適的畫筆屬性社证,完成你的繪制逼龟。

2.2 Canvas

Canvas是繪制的畫布,它包含了很多繪制方法追葡,可以繪制出各種形狀的圖形腺律。需要注意的是奕短,畫布是應(yīng)用所有控件都在使用的, 所以通過這個(gè)畫布其實(shí)是可以繪制充滿屏幕的內(nèi)容的,每次繪制都應(yīng)該限制在本控件的區(qū)域(Size)內(nèi), 以免繪制覆蓋到其他組件匀钧。
下面介紹下Canvas的繪制方法:

2.2.1 繪制點(diǎn)
void drawPoints(PointMode pointMode, List<Offset> points, Paint paint)

PointMode是個(gè)枚舉

enum PointMode {
  /// Draw each point separately.僅繪制單獨(dú)的點(diǎn)
  points,
  /// Draw each sequence of two points as a line segment.繪制連線翎碑,兩兩連線
  lines,
  /// Draw the entire sequence of point as one line.繪制封閉連線,上個(gè)點(diǎn)連接下個(gè)點(diǎn)
  polygon,
}
Offset是相對(duì)于繪制區(qū)域的偏移坐標(biāo)之斯,可以定義點(diǎn)坐標(biāo)
2.2.2 繪制線
void drawLine(Offset p1, Offset p2, Paint paint)

p1日杈、p2為線段兩個(gè)端點(diǎn)

2.2.3 繪制矩形
void drawRect(Rect rect, Paint paint)

Rect定義矩形的大小位置,有多種構(gòu)造方式:

//使用左上和右下角坐標(biāo)來確定矩形的大小和位置
fromPoints(Offset a, Offset b)
//使用圓的圓心點(diǎn)坐標(biāo)和半徑和確定外切矩形的大小和位置
fromCircle({ Offset center, double radius })
//使用矩形左邊的X坐標(biāo)佑刷、矩形頂部的Y坐標(biāo)莉擒、矩形右邊的X坐標(biāo)、矩形底部的Y坐標(biāo)來確定矩形的大小和位置
fromLTRB(double left, double top, double right, double bottom)
//使用矩形左邊的X坐標(biāo)瘫絮、矩形頂部的Y坐標(biāo)矩形的寬高來確定矩形的大小和位置
fromLTWH(double left, double top, double width, double height)
2.2.4 繪制圓角矩形
void drawRRect(RRect rrect, Paint paint)

RRect描述圓角矩形涨冀,他通過Rect和Radius來構(gòu)造

RRect.fromRectAndRadius(rect, radius)
//舉例說明
Rect rect = Rect.fromCircle(center: Offset(100.0, 200.0), radius: 30.0);   
RRect rrect = RRect.fromRectAndRadius(rect, Radius.circular(20.0));
2.2.5 繪制圓
void drawCircle(Offset c, double radius, Paint paint)

畫圓比較簡單,c表示圓心位置檀何,radius是半徑蝇裤。

2.2.6 繪制橢圓
void drawOval(Rect rect, Paint paint)

橢圓使用外接矩形確定大小位置,rect就是外接矩形频鉴。

2.2.7 繪制弧形
void drawArc(Rect rect, double startAngle, double sweepAngle, bool useCenter, Paint paint)

繪制弧形栓辜,先確定弧形對(duì)應(yīng)的橢圓,同樣地用外接矩形rect確定橢圓垛孔,然后根據(jù)起始點(diǎn)和結(jié)束點(diǎn)角度來確定那一段弧度藕甩,startAngle,sweepAngle分別代表起始和結(jié)束點(diǎn)角度周荐,角度用弧度表示法狭莱。
useCenter表示是否連接閉合形狀,userCenter = false表示不閉合概作,即畫一段弧線腋妙,userCenter = true表示閉合,即繪制一個(gè)扇形讯榕。

2.2.8 繪制路徑
void drawPath(Path path, Paint paint)

繪制路徑骤素,關(guān)鍵在于構(gòu)建路徑Path,可以直接new Path對(duì)象愚屁,然后通過path方法可以連接出圖形厦酬,path關(guān)鍵方法如下:

moveTo  //移動(dòng)到路徑起始位置
lineTo  //用直線連接指定點(diǎn)
arcTo   //用曲線連接到指定點(diǎn)
conicTo //用二階貝塞爾曲線連接到指定點(diǎn)
cubicTo    //用三階貝塞爾曲線連接到指定點(diǎn)
contains    //判斷當(dāng)前路徑上是否包含某點(diǎn)
close   //路徑閉合签舞,用直線連接到起始點(diǎn)
reset   //重置路徑,恢復(fù)到默認(rèn)狀態(tài)

還有其他方法,有興趣可以查看API醋闭。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末顿涣,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌唁桩,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件浴讯,死亡現(xiàn)場離奇詭異朵夏,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)榆纽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門仰猖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人奈籽,你說我怎么就攤上這事饥侵。” “怎么了衣屏?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵躏升,是天一觀的道長。 經(jīng)常有香客問我狼忱,道長膨疏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任钻弄,我火速辦了婚禮佃却,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘窘俺。我一直安慰自己饲帅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布瘤泪。 她就那樣靜靜地躺著灶泵,像睡著了一般。 火紅的嫁衣襯著肌膚如雪对途。 梳的紋絲不亂的頭發(fā)上赦邻,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天,我揣著相機(jī)與錄音实檀,去河邊找鬼惶洲。 笑死,一個(gè)胖子當(dāng)著我的面吹牛劲妙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播儒喊,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼镣奋,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了怀愧?” 一聲冷哼從身側(cè)響起侨颈,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤余赢,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后哈垢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體妻柒,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年耘分,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了举塔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡求泰,死狀恐怖央渣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情渴频,我是刑警寧澤芽丹,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站卜朗,受9級(jí)特大地震影響拔第,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜场钉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一蚊俺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惹悄,春花似錦春叫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至当纱,卻和暖如春呛每,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背坡氯。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工晨横, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人箫柳。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓手形,卻偏偏與公主長得像,于是被迫代替她去往敵國和親悯恍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子库糠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容