[Android] 零碎知識(shí)匯總 - View相關(guān)

前言

開始意識(shí)到犀变,知識(shí)"縫合"的重要性膳算,只要沒有開始學(xué)會(huì)表述,看書再多弛作,終究會(huì)忘記涕蜂。

ok,這一篇映琳,用來記錄View的相關(guān)小知識(shí)點(diǎn)机隙,持續(xù)更新與整理。

關(guān)于 View 繪制流程

  • onMeasure(): 尺寸大小
  • onLayout(): 擺放位置
  • onDraw(): 圖層繪制

簡單來說萨西,自定義 View 時(shí)有鹿,最重要的就是這三個(gè)方法。個(gè)人認(rèn)為谎脯,其中 onDraw() 是最關(guān)鍵的葱跋,也是最難的,其中牽扯到一大堆坐標(biāo)的計(jì)算源梭,暈~

簡單說一下娱俺,自己的理解:

  • onMeasure()
    • 繼承自 View 的話,就只是計(jì)算自己的尺寸废麻。
    • 繼承自 ViewGroup 的話荠卷,就先要計(jì)算每一個(gè)子 View 的寬高,并為其 mMeasuredWidth 和 mMeasuredHeight 這兩個(gè)屬性賦值烛愧,最近才計(jì)算出自己的尺寸油宜。
    • 為了適配的話掂碱,可以嘗試使用 resolveSize()。
  • onSizeChanged()
    • 提一嘴這個(gè)慎冤,個(gè)人比較常用疼燥,它在構(gòu)造方法、onMeasure() 之后蚁堤,又在 onDraw() 之前悴了,此時(shí)已經(jīng)完成全局變量初始化,也得到了控件的寬高违寿;
    • 所以可以在這個(gè)方法中確定一些與寬高有關(guān)的數(shù)值,比如這個(gè) View 的寬高半徑熟空,Padding 等藤巢,方便繪制的時(shí)候計(jì)算大小和位置。
  • onLayout()
    • 這個(gè)方法本身息罗,其實(shí)是為了控制子 View 在自己中的擺放位置掂咒。
    • 繼承自 View 的話,onLayout() 方法為空實(shí)現(xiàn)迈喉,畢竟沒娃 = =
    • 繼承自 ViewGroup 的話绍刮,需要復(fù)寫,因?yàn)橛泻⒆影
  • onDraw()
    • 其實(shí) View 最終都是調(diào)用 draw() 方法進(jìn)行繪制的挨摸,然而平常都是復(fù)寫onDraw()方法進(jìn)行繪制孩革,沒懂這兩者之間的關(guān)系 = =
    • 需要先調(diào)用 super.draw() 完成系統(tǒng)的繪制,再進(jìn)行自定義的繪制得运。
    • ViewGroup 中膝蜈,dispatchDraw() 發(fā)起對(duì)子視圖的繪制,具體沒研究過熔掺。

附圖一張饱搏,能夠非常清晰的說明,整個(gè)繪制流程置逻。同時(shí)推沸,也說明了,invalidate() 和 requestLayout() 的區(qū)別券坞。


奉上原圖鏈接: https://lh3.googleusercontent.com/-TTZ-LN41ygA/UIQt75DBSEI/AAAAAAAAFAY/v8jAR9WWg5w/w829-h1463-p-rw/android.png

關(guān)于 View 的刷新機(jī)制

所謂的刷新機(jī)制鬓催,一句話說清楚,就是:子通知父開始刷新恨锚,父控制子的刷新操作深浮。
常用的有兩種刷新方式,invalidate()眠冈,requestLayout();
其實(shí)區(qū)別飞苇,再上圖中已經(jīng)說明了菌瘫,
** requestLayout() 比 invalidate() 多走了 measure 與 layout 這兩個(gè)流程 **
因此:

  • requestLayout() 常用于當(dāng) View 發(fā)生位移,旋轉(zhuǎn)等 LayoutParams 發(fā)生變化的場景布卡;
  • invalidate() 則只是對(duì)當(dāng)前 View 進(jìn)行重繪雨让,不會(huì)進(jìn)行測量、布局流程

額外提一句忿等,
** postInvalidate() 是在非UI線程中調(diào)用栖忠,invalidate() 則是在UI線程中調(diào)用。**

關(guān)于 onDraw() 再多BB兩句

  • 要對(duì)各個(gè)坐標(biāo)很熟悉贸街,這個(gè)很重要庵寞,詳情請(qǐng)參考 http://blog.csdn.net/jason0539/article/details/42743531
  • 要對(duì) Canvas(畫布) 和 Paint(畫筆)的各個(gè)方法比較熟悉,比如** drawBitmap()薛匪,drawOval()捐川,drawArc() **等

我真正想說的是,drawText()逸尖,這個(gè)很奇葩古沥,吃了不少苦頭,先看看官方描述:



** 注意娇跟,關(guān)于 y 的描述岩齿,有一個(gè)詞 baseline ** ,Android中苞俘,對(duì)文字有顯示盹沈,劃分了五條線,有點(diǎn)像小時(shí)候?qū)懫匆魰r(shí)的那個(gè)吃谣,其中第三條線襟诸,叫做 baseline,也就是說基协,xy參數(shù)歌亲,并不是常用的左上角坐標(biāo) = =




另外再說一句,在使用drawText()澜驮,處理文本(單個(gè)字符)居中時(shí)陷揪,有時(shí)候總是對(duì)不齊,請(qǐng)檢查杂穷,** 文字的寬度悍缠,和,外接矩形的寬度是否一致 **耐量,找不到特別合適的圖飞蚓,將就一下吧 = =

textSmallWidth 是數(shù)字3的真實(shí)寬度,而 mTextRect.height() 是外接矩形的高度廊蜒,
額趴拧,這個(gè)解釋一下溅漾,mTextRect.height() 是大于等于 mTextRect.width() 的,當(dāng)內(nèi)容是單個(gè)字符的時(shí)候著榴,height = width

mTextPaint.getTextBounds("3", 0, timeText.length(), mTextRect); 

這段代碼可以獲取到添履,數(shù)字3繪制時(shí)的真實(shí)寬度。

對(duì)自定義View進(jìn)行控制

這一段是在別人的博客上看到的脑又,我覺得很有用暮胧,摘抄至此。盡管我都知道问麸,但是沒有總結(jié)過往衷。

  1. 如果想控制 View 在屏幕上的渲染效果,就在重寫 onDraw() 方法严卖,在里面進(jìn)行相應(yīng)的處理席舍。

  2. 如果想要控制用戶與 View 之間的交互操作,則在 onTouchEvent() 方法中對(duì)手勢進(jìn)行控制處理妄田。

  3. 如果想要控制 View 中內(nèi)容在屏幕上顯示的尺寸大小,就重寫 onMeasure() 方法中進(jìn)行處理驮捍。

  4. 在 XML文件中設(shè)置自定義View的XML屬性疟呐。

  5. 如果想避免失去 View 的相關(guān)狀態(tài)參數(shù)的話,就在 onSaveInstanceState() 和 onRestoreInstanceState() 方法中保存有關(guān)View的狀態(tài)信息东且。

總結(jié)

第一次開始寫启具,沒有想象中的難,只要一開始寫珊泳,就會(huì)不斷面臨選擇從而最終達(dá)到目的鲁冯,最可怕的就是,永遠(yuǎn)停留在開始前的那一刻色查,遲遲不肯動(dòng)筆薯演。
整個(gè)過程,花了很久秧了,整理自己的思路跨扮,找合適的圖,本以為30分鐘就該搞定了验毡,= =
果然衡创,項(xiàng)目實(shí)際時(shí)間 = 預(yù)估時(shí)間 * 5;
寫的有錯(cuò)的地方晶通,望各位大牛指正璃氢,可能邏輯不夠清晰,語言有些啰嗦狮辽,奈何小學(xué)語文沒畢業(yè)~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末一也,一起剝皮案震驚了整個(gè)濱河市巢寡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌塘秦,老刑警劉巖讼渊,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異尊剔,居然都是意外死亡爪幻,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門须误,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挨稿,“玉大人,你說我怎么就攤上這事京痢∧谈剩” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵祭椰,是天一觀的道長臭家。 經(jīng)常有香客問我,道長方淤,這世上最難降的妖魔是什么钉赁? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮携茂,結(jié)果婚禮上你踩,老公的妹妹穿的比我還像新娘。我一直安慰自己讳苦,他們只是感情好带膜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鸳谜,像睡著了一般膝藕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上咐扭,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天束莫,我揣著相機(jī)與錄音,去河邊找鬼草描。 笑死览绿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的穗慕。 我是一名探鬼主播饿敲,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼逛绵!你這毒婦竟也來了怀各?” 一聲冷哼從身側(cè)響起倔韭,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瓢对,沒想到半個(gè)月后寿酌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡硕蛹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年醇疼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片法焰。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡秧荆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出埃仪,到底是詐尸還是另有隱情乙濒,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布卵蛉,位于F島的核電站颁股,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏傻丝。R本人自食惡果不足惜甘有,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望桑滩。 院中可真熱鬧梧疲,春花似錦允睹、人聲如沸运准。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胁澳。三九已至,卻和暖如春米者,著一層夾襖步出監(jiān)牢的瞬間韭畸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來泰國打工蔓搞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留胰丁,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓喂分,卻偏偏與公主長得像锦庸,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蒲祈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

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