requestLayout()引起的問題

requestLayout()引起的問題

網(wǎng)上有大量寫的很深入的requestLayout()源碼分析的文章或杠。故這里不再寫了滨彻,只做一個實際情況下遇到的問題的分析搔确。

起因:

自定義了一個CircleImageView绝页,功能是調(diào)用setImage(Bitmap bitmap)后可以將圖片以圓形加載民泵。

本以為直接在setImage(Bitmap)的結(jié)尾直接調(diào)用requestLayout()即可迄汛。

這里從兩個方面寫:

xml中定義為wrap_content

當(dāng)LayoutParamswrap_content時捍壤,我處理的邏輯是:在onMeasure()中根據(jù)寬高的MeasureSpec是否等于MeasureSpec.AT_MOST,如果等于鞍爱,那么在第一次繪制的時候鹃觉,setMeasureDimension()都設(shè)置成0,而當(dāng)調(diào)用了setBitmap()時硬霍,獲取圖片的寬高并保存帜慢,然后調(diào)用requestLayout(),此舉引起onMeasure(),那么在此處將圖片的寬高設(shè)置到setMeasureDimension()中粱玲,而整體的View的測量大小就是圖片大小了躬柬。

此時我的onMeasuresetBitmap長這樣:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    Log.d(TAG, "onMeasure: ");
    int ws = MeasureSpec.getSize(widthMeasureSpec);
    int hs = MeasureSpec.getSize(heightMeasureSpec);
    int wm = MeasureSpec.getMode(widthMeasureSpec);
    int hm = MeasureSpec.getMode(heightMeasureSpec);
    //如果子view是wrap_content,那么view就設(shè)置成bitmap的大小抽减。
    if (wm == MeasureSpec.AT_MOST) {
        ws = bitmapW;
    }
    if (hm == MeasureSpec.AT_MOST) {
        hs = bitmapH;
    }
    int resultW = MeasureSpec.makeMeasureSpec(ws, wm);
    int resultH = MeasureSpec.makeMeasureSpec(hs, hm);
    super.onMeasure(resultW, resultH);
}
public void setImage(Bitmap bitmap) {
    mBitmap = bitmap;
    bitmapH = mBitmap.getHeight();
    bitmapW = mBitmap.getWidth();
    requestLayout();//最后要調(diào)用一個requestLayout允青,引起onMeasure()和onLayout()。
}

大小不同的兩張圖片

此時為這個CircleImageView準(zhǔn)備了兩張分辨率不同的圖片卵沉,點擊按鈕A加載圖片A颠锉,點擊按鈕B加載圖片B。

點擊情況:

  1. 由顯示A的情況下加載B史汗,或者顯示B的情況下加載A琼掠,或者從沒有圖片情況下點擊加載A或B,分別引起了onMeasure(),onSizeChanged(),onLayout(),onDraw回調(diào)停撞。成功地在onDraw重新drawBitmap()切換了圖片瓷蛙。
  2. 當(dāng)在A圖片下點擊按鈕A,或者在B圖片下點擊按鈕B戈毒。只引起了onMeasure()onLayout()回調(diào)艰猬。這里少了一個onSizeChanged()很好理解,因為在該情況下埋市,setMeasureDimesion()傳入的值和上一次一樣冠桃,View中可以很容易通過這種判斷而跳過onSizeChanged()回調(diào),而至于為什么onDraw()回調(diào)沒有引起道宅,這點我也很疑惑食听。

大小相同的兩張圖片

此時我又準(zhǔn)備了兩張大小相同的圖片。操作和上述一樣污茵。

點擊情況:

  1. 從沒有圖片的情況下點擊加載圖片A:onMeasure(),onSizeChanged(),onLayout(),onDraw
  2. 從圖片A點擊加載圖片B:加載失敗碳蛋,圖片仍然停留在圖片A,此時的回調(diào)是:onMeasure()和`onLayout()`
  3. 圖片A點擊加載圖片A: 同2省咨。

推論:(在wrap_content情況下)

  1. 當(dāng)requestLayout()調(diào)用時,一定會引起onMeasure()onLayout()玷室。
  2. 當(dāng)requestLayout()調(diào)用時零蓉,如果沒有在setMeasureDimension()中傳入和上次不同的測量值的話,一定不會引起onSizeChanged()onDraw()穷缤。onSizeChanged()不被調(diào)用的原因很容易在onLayout()的源碼中找到答案敌蜂,而onDraw()不引起回調(diào)的原因目前還不明白。

xml中定義為精確值

  1. 情況:此時圖片直接無法加載津肛。僅僅在第一次實例化CircleImageView的時候會依次調(diào)用onMeasure(),onSizeChanged(),onLayout(),onDraw章喉,伺候每一次調(diào)用setImage()都只會引起onMeasure()onLayout()

  2. 原因:因為在requestLayout()調(diào)用后,因為此時的測量模式是EXACTLY秸脱,因此setMeasuredDimension()中傳入的值永遠(yuǎn)不變落包,永遠(yuǎn)都是xml中定義的那個精確值。而上文的推論中指出摊唇,setMeasuredDimension()傳入的值等于原本的測量值的話咐蝇,直接引起onSizeChanged()onDraw()無法調(diào)用。


結(jié)論

  1. 上文中的推論
  2. 不能依賴requestLayout來引起onDraw()回調(diào)巷查,如果百分之百確定要繪制有序,直接調(diào)用invalidate()postInvalidate(),他們只會引起onDraw()的回調(diào)岛请。
  3. CircleImageView源碼:https://github.com/William619499149/anddroid-little-bubble/blob/master/CircleImageView.java
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末旭寿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子崇败,更是在濱河造成了極大的恐慌盅称,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件僚匆,死亡現(xiàn)場離奇詭異微渠,居然都是意外死亡,警方通過查閱死者的電腦和手機咧擂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門逞盆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人松申,你說我怎么就攤上這事云芦。” “怎么了贸桶?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵舅逸,是天一觀的道長。 經(jīng)常有香客問我皇筛,道長琉历,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任水醋,我火速辦了婚禮旗笔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拄踪。我一直安慰自己蝇恶,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布惶桐。 她就那樣靜靜地躺著撮弧,像睡著了一般潘懊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贿衍,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天授舟,我揣著相機與錄音,去河邊找鬼舌厨。 笑死岂却,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的裙椭。 我是一名探鬼主播躏哩,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼揉燃!你這毒婦竟也來了扫尺?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤炊汤,失蹤者是張志新(化名)和其女友劉穎正驻,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抢腐,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡姑曙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了迈倍。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伤靠。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖啼染,靈堂內(nèi)的尸體忽然破棺而出宴合,到底是詐尸還是另有隱情,我是刑警寧澤迹鹅,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布卦洽,位于F島的核電站,受9級特大地震影響斜棚,放射性物質(zhì)發(fā)生泄漏阀蒂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一弟蚀、第九天 我趴在偏房一處隱蔽的房頂上張望脂新。 院中可真熱鬧,春花似錦粗梭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽滞乙。三九已至,卻和暖如春鉴嗤,著一層夾襖步出監(jiān)牢的瞬間斩启,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工醉锅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留兔簇,地道東北人。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓硬耍,卻偏偏與公主長得像垄琐,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子经柴,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,724評論 2 351

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