自定義View—測(cè)量寬高遇到的問題

例1. 缺少默認(rèn)值 | 自己寫的

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        int finalWidth, finalHeight;

        // 不明
        finalWidth = getSuggestedMinimumWidth();
        finalHeight = getSuggestedMinimumHeight();

        if (widthMode == MeasureSpec.EXACTLY) {
            finalWidth = widthSize;
        } else if (widthMode == MeasureSpec.AT_MOST) {
            int padding = getPaddingLeft() + getPaddingRight();
            finalWidth += padding;
        }

        if (heightMode == MeasureSpec.EXACTLY) {
            finalHeight = heightSize;
        } else if (heightMode == MeasureSpec.AT_MOST) {
            int padding = getPaddingTop() + getPaddingBottom();
            finalHeight += padding;
        }

        setMeasuredDimension(finalWidth, finalHeight);
    }

① 上面的例子中缺少默認(rèn)值,所以高度為0

例2. 指定默認(rèn)寬高 | 對(duì)第三種測(cè)量模式UNSPECIFIED的理解

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    int desiredWidth = 100;
    int desiredHeight = 100;

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    int width;
    int height;

    //Measure Width
    if (widthMode == MeasureSpec.EXACTLY) {
        //Must be this size
        width = widthSize;
    } else if (widthMode == MeasureSpec.AT_MOST) {
        //Can't be bigger than...
        width = Math.min(desiredWidth, widthSize);
    } else {
        //Be whatever you want
        width = desiredWidth;
    }

    //Measure Height
    if (heightMode == MeasureSpec.EXACTLY) {
        //Must be this size
        height = heightSize;
    } else if (heightMode == MeasureSpec.AT_MOST) {
        //Can't be bigger than...
        height = Math.min(desiredHeight, heightSize);
    } else {
        //Be whatever you want
        height = desiredHeight;
    }

    //MUST CALL THIS
    setMeasuredDimension(width, height);

解決的方法總結(jié):

  1. 指定一個(gè)默認(rèn)的內(nèi)部寬高喻括,例如本方法中的desiredWidth = 100。
  2. 判斷當(dāng)MeasureSpec的模式為AT_MOST(對(duì)應(yīng)于wrap_content)時(shí)驰徊,設(shè)置結(jié)果為設(shè)置的值(最大為我們?cè)O(shè)置的值,如果小于設(shè)置值就設(shè)置為specSize)堕阔。
  3. 判斷當(dāng)MeasureSpec的模式為非AT_MOST時(shí)棍厂,直接設(shè)置為系統(tǒng)的測(cè)量值即可。
  4. 設(shè)置值沒有特定的標(biāo)準(zhǔn)超陆,以實(shí)際情況為準(zhǔn)牺弹。

以上作者:Jinlin
鏈接:http://www.reibang.com/p/95b98edda6ac

例3. 寬高默認(rèn)值

     @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 
        setMeasuredDimension(measureWidth(widthMeasureSpec),
                measureHeight(heightMeasureSpec));
 
    }
 
    private int measureHeight(int measureSpec) {
        int result = 0;
        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);
 
        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            result=75;
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size);
            }
        }
        return result;
 
    }
 
    private int measureWidth(int measureSpec) {
        int result = 0;
        int mode = MeasureSpec.getMode(measureSpec);
        int size = MeasureSpec.getSize(measureSpec);
 
        if (mode == MeasureSpec.EXACTLY) {
            result = size;
        } else {
            result = 75;//根據(jù)自己的需要更改
            if (mode == MeasureSpec.AT_MOST) {
                result = Math.min(result, size);
            }
        }
        return result;
 
    }



③ UNSPECIFIED 這種模式不指定測(cè)量模式,view大小沒有限制时呀,想多大就多大张漂。

版權(quán)聲明:本文為CSDN博主「mxiaoyem」的原創(chuàng)文章,遵循CC 4.0 by-sa版權(quán)協(xié)議谨娜,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明航攒。
原文鏈接:https://blog.csdn.net/mxiaoyem/article/details/51077054

另外(https://www.cnblogs.com/wjtaigwh/p/6600035.html

如果我們的自定義控件在布局文件中,只需要設(shè)置指定的具體寬高趴梢,或者M(jìn)ATCH_PARENT 的情況漠畜,我們可以不用重寫onMeasure方法。

但如果自定義控件需要設(shè)置包裹內(nèi)容WRAP_CONTENT 坞靶,我們需要重寫onMeasure方法憔狞,為控件設(shè)置需要的尺寸;默認(rèn)情況下WRAP_CONTENT 的處理也將填充整個(gè)父控件彰阴。

onMeasure方法最后需要調(diào)用setMeasuredDimension方法來(lái)保存測(cè)量的寬高值瘾敢。

題外話

例1中,發(fā)現(xiàn)在onMeasure()里最終確定寬高時(shí)調(diào)用setMeasuredDimension()尿这。
在onSizeChanged()中g(shù)etMeasuredWidth()/getMeasuredHeight()廉丽,get方法得到的數(shù)值應(yīng)該就是onMeasure()中set方法確定的。


set()/get()

// 點(diǎn)進(jìn)去看看源碼就知道了


setMeasuredDimension()一直往里點(diǎn)
getMeasuredWidth()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末妻味,一起剝皮案震驚了整個(gè)濱河市正压,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌责球,老刑警劉巖焦履,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異雏逾,居然都是意外死亡嘉裤,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門栖博,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)屑宠,“玉大人,你說(shuō)我怎么就攤上這事仇让〉浞睿” “怎么了躺翻?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)卫玖。 經(jīng)常有香客問我公你,道長(zhǎng),這世上最難降的妖魔是什么假瞬? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任陕靠,我火速辦了婚禮,結(jié)果婚禮上脱茉,老公的妹妹穿的比我還像新娘剪芥。我一直安慰自己,他們只是感情好琴许,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布粗俱。 她就那樣靜靜地躺著,像睡著了一般虚吟。 火紅的嫁衣襯著肌膚如雪寸认。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天串慰,我揣著相機(jī)與錄音偏塞,去河邊找鬼。 笑死邦鲫,一個(gè)胖子當(dāng)著我的面吹牛灸叼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播庆捺,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼古今,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了滔以?” 一聲冷哼從身側(cè)響起捉腥,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎你画,沒想到半個(gè)月后抵碟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡坏匪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年拟逮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片适滓。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出罚屋,到底是詐尸還是另有隱情苦囱,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布沿后,位于F島的核電站沿彭,受9級(jí)特大地震影響朽砰,放射性物質(zhì)發(fā)生泄漏尖滚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一瞧柔、第九天 我趴在偏房一處隱蔽的房頂上張望漆弄。 院中可真熱鬧,春花似錦造锅、人聲如沸撼唾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)倒谷。三九已至,卻和暖如春糙箍,著一層夾襖步出監(jiān)牢的瞬間渤愁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工深夯, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抖格,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓咕晋,卻偏偏與公主長(zhǎng)得像雹拄,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子掌呜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348