八圆丹、自定義View之使用貝塞爾曲線繪制可拖拽小紅點(diǎn)

該項(xiàng)目屬于繼承自View的自定義控件。

效果圖如下:




1.靜態(tài)繪制粘性控件

粘性控件由兩個(gè)點(diǎn)和中間的貝塞爾曲線組成抖仅。效果圖如下:

靜態(tài)繪制可拖拽小圓點(diǎn)

分析圖如下:


靜態(tài)繪制粘性控件分析圖

總體來說:粘性控件兩個(gè)小圓點(diǎn)之間的區(qū)域使用貝塞爾曲線繪制交煞,貝塞爾曲線有三個(gè)點(diǎn)咏窿,起始點(diǎn),終點(diǎn)和控制點(diǎn)素征。第一條貝塞爾曲線起始點(diǎn)為固定圓的上半圓弧水平切點(diǎn)翰灾,第二條貝塞爾曲線的起始點(diǎn)為固定圓下半圓弧水平方向的切點(diǎn)。兩條貝塞爾曲線的終點(diǎn)和控制點(diǎn)起始狀態(tài)的位置如圖所示稚茅。終點(diǎn)為拖拽圓上下半圓弧水平方向的切點(diǎn)纸淮,控制點(diǎn)是圓心連線的中點(diǎn)。后面動(dòng)態(tài)繪制時(shí)亚享,兩條貝塞爾曲線的終點(diǎn)和控制點(diǎn)是隨著拖拽圓的移動(dòng)而改變的咽块,這是后話。

1)在onDraw()中繪制兩個(gè)小圓點(diǎn):

繪制兩個(gè)圓

2) 繪制貝塞爾曲線欺税,使用Path類

首先確定貝塞爾曲線的起始點(diǎn)侈沪,終點(diǎn)坐標(biāo)。如下圖分析所示:

貝塞爾曲線起始位置點(diǎn)坐標(biāo)分析

分別獲得了兩條貝塞爾曲線三個(gè)點(diǎn)的坐標(biāo)晚凿,首先把起點(diǎn)亭罪,終點(diǎn)封裝起來,避免用錯(cuò)歼秽。

開始繪制貝塞爾曲線应役,使用Path類,具體用法代碼中已注釋

其中需要注意的是,貝塞爾曲線是一個(gè)閉合的曲線箩祥,如果只有兩個(gè)點(diǎn)院崇,它會(huì)自動(dòng)連接起點(diǎn)和終點(diǎn),因此我們畫第二條貝塞爾曲線時(shí)袍祖,直接把第二條的終點(diǎn)和第一條的終點(diǎn)連接起來底瓣,將4個(gè)點(diǎn)逆時(shí)針連接,lineTo(x,y)是畫連線的意思蕉陋,將曲線終點(diǎn)連接到(x,y) moveTo(x,y)是直接跳到(x,y)

此時(shí)捐凭,靜態(tài)的拖拽小圓點(diǎn)已經(jīng)繪制完成,明天更新動(dòng)態(tài)拖拽小紅點(diǎn)的內(nèi)容凳鬓。

2茁肠、繪制動(dòng)態(tài)拖拽小紅點(diǎn)

原理:根據(jù)手指在屏幕上的觸摸點(diǎn)和MOVE事件,更改drag圓的圓心坐標(biāo)村视,根據(jù)圓心坐標(biāo)和斜率求出繪制貝塞爾曲線需要的5個(gè)點(diǎn)。需要注意的是酒奶,在拖拽的過程中蚁孔,這5個(gè)點(diǎn)是一直隨著dragCenter的變化而變化的。

如圖所示:

如圖所示:5個(gè)點(diǎn)分別是

1.controlPoint控制點(diǎn)? 2.stickyPointp[0],dragPoint[0]第一條貝塞爾曲線的起點(diǎn)和終點(diǎn)惋嚎。3.dragPoint[1],stickyPoint[1] 第二條貝塞爾曲線的起點(diǎn)和終點(diǎn)杠氢。

那么怎么樣求出這5個(gè)點(diǎn)呢? 一步步來

1另伍、 controlPoint 兩圓圓心連線的黃金分割點(diǎn)鼻百。根據(jù)兩圓圓心坐標(biāo)和比例0.618求出該點(diǎn)坐標(biāo)

2.求出斜率

3.根據(jù)斜率求出4個(gè)點(diǎn)

代碼如下:

根據(jù)dragCenter的改變,動(dòng)態(tài)求出5個(gè)點(diǎn)之后摆尝,就可以動(dòng)態(tài)的繪制貝塞爾曲線温艇,我們需要在onTouchEvent中,把Down 和Move 事件下獲得手指移動(dòng)的坐標(biāo)堕汞,作為dragCenter的坐標(biāo)勺爱,并且每次進(jìn)行onToucheEvent時(shí),都要對畫面進(jìn)行重繪讯检。每次重繪都會(huì)更新點(diǎn)坐標(biāo)琐鲁,完成拖拽行為在屏幕上的實(shí)現(xiàn)。

onTouchEvent()代碼的實(shí)現(xiàn):

此時(shí)人灼,效果如下:

可以看到围段,手指點(diǎn)到的位置,與dragCenter稍微有點(diǎn)偏移投放,這是因?yàn)楂@取的是點(diǎn)相對于屏幕的x奈泪,y坐標(biāo),而StatusBar 占了畫布一點(diǎn)距離。因此段磨,我們需要把畫布整體往上偏移即可取逾。

canvas.translate(0, -GeometryUtil.getStatusBarHeight(getResources()));

一些優(yōu)化:(為什么每次傳入值,屏幕上的值就可以動(dòng)態(tài)的變化呢苹支,這是因?yàn)樵趏nTounchEvent

中調(diào)用了invalidate()重繪界面)

優(yōu)化1.固定圓的半徑隨著兩圓之間的距離變大砾隅,而不斷的變小。到達(dá)一定的距離后就消失不見债蜜。

首先解決stickyRadius隨著兩圓之間的距離變大而不斷變小晴埂。

代碼如下:在onDraw()中,每次重繪界面都會(huì)改變stickyRadius值

然后解決寻定,拖拽到一定程度時(shí)儒洛,中間連接的部分?jǐn)嗟簦潭▓A消失狼速。

首先設(shè)置一個(gè)boolean isDragOut = true;

在onTouchEvent()中琅锻,拖拽的過程中,即MOVE事件中向胡,判斷兩圓圓心的距離是否大于設(shè)定的最大值恼蓬,這里是200,如果大僵芹,則將isDragOut = false处硬;在onDraw()中 不再繪制貝塞爾曲線和固定圓部分,代碼如下:

onDraw()中

優(yōu)化2.手松開時(shí)拖拽圓的優(yōu)化拇派。

分幾種情況

1.手松開時(shí)荷辕,已經(jīng)拖拽出了最大范圍,此時(shí)拖拽圓回去件豌。

2.手松開時(shí)疮方,沒有拖拽出最大范圍,此時(shí)拖拽圓以動(dòng)畫的形式彈回去

3.手松開時(shí)茧彤,沒有拖拽出最大范圍案站,但曾經(jīng)拖拽出最大范圍過,直接回去棘街,不用動(dòng)畫的狀態(tài)彈回去

代碼如下

至此蟆盐,自定義View暫時(shí)告一段落,等我把谷歌市場和華為市場兩個(gè)項(xiàng)目寫完遭殉,再繼續(xù)更新一些比較難的自定義View的博客石挂,參考Hencoder的公眾號,做一些現(xiàn)在比較常用的自定義View险污。

今年的計(jì)劃基本上是這樣:

1.谷歌市場 2.華為市場 3.java數(shù)據(jù)結(jié)構(gòu)和算法? java編程思想 學(xué)完了Android中的東西痹愚,就開始學(xué)習(xí)后端的知識

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末富岳,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子拯腮,更是在濱河造成了極大的恐慌窖式,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件动壤,死亡現(xiàn)場離奇詭異萝喘,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)琼懊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門阁簸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人哼丈,你說我怎么就攤上這事启妹。” “怎么了醉旦?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵饶米,是天一觀的道長。 經(jīng)常有香客問我车胡,道長檬输,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任吨拍,我火速辦了婚禮褪猛,結(jié)果婚禮上网杆,老公的妹妹穿的比我還像新娘羹饰。我一直安慰自己,他們只是感情好碳却,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布队秩。 她就那樣靜靜地躺著,像睡著了一般昼浦。 火紅的嫁衣襯著肌膚如雪馍资。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天关噪,我揣著相機(jī)與錄音鸟蟹,去河邊找鬼。 笑死使兔,一個(gè)胖子當(dāng)著我的面吹牛建钥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播虐沥,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼熊经,長吁一口氣:“原來是場噩夢啊……” “哼泽艘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起镐依,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤匹涮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后槐壳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體然低,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年宏粤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了脚翘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡绍哎,死狀恐怖来农,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情崇堰,我是刑警寧澤沃于,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站海诲,受9級特大地震影響繁莹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜特幔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一咨演、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蚯斯,春花似錦薄风、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至横辆,卻和暖如春撇他,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背狈蚤。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工困肩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人脆侮。 一個(gè)月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓锌畸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親他嚷。 傳聞我的和親對象是個(gè)殘疾皇子蹋绽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354

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

  • 一芭毙、Path常用方法表 二.Path詳解 上一次除了一些常用函數(shù)之外,講解的基本上都是直線卸耘,本次需要了解其中的曲線...
    呂侯爺閱讀 1,556評論 1 6
  • 前言 之前沒有見到有封裝好的類似QQ小紅點(diǎn)的控件退敦,雖然公司項(xiàng)目中并沒有使用到該效果,不過出于練習(xí)與回顧的角度決定自...
    小甜李子閱讀 469評論 0 0
  • 前一篇文章講了Path繪制直線以及各種基本圖形蚣抗,這篇文主要說Path繪制曲線侈百,就是曲線中非常有名的貝賽爾曲線。貝賽...
    Jackson杰閱讀 2,262評論 0 13
  • 夜微涼翰铡,清風(fēng)偶拂面钝域,聞得蛙鳴陣陣。且看蒼穹锭魔,皓月千里例证,繁星璀璨,人月相對迷捧,無言卻生萬分嘆织咧! 古往今來,時(shí)移世易漠秋。陰...
  • 魏麗玲@4月23日 領(lǐng)導(dǎo)者的資質(zhì)#8期#關(guān)愛組【學(xué)委】 河北惠友集團(tuán) 一笙蒙、【知~勤學(xué)】 《領(lǐng)導(dǎo)者的十項(xiàng)資質(zhì)》3遍 ...
    qin123456閱讀 172評論 0 0