android中獲取view在布局中的高度和寬度

有時(shí)需要在 onCreate() 方法中獲取某個(gè) View 組件的寬度和高度未桥,而直接調(diào)用 getWidth()肠骆、getHeight()肺蔚、getMeasuredWidth()加矛、getMeasuredHeight() 方法只會得到 0履婉。

實(shí)現(xiàn)方法
一、使用 View.measure 測量 View
該方法測量的寬度和高度可能與視圖繪制完成后的真實(shí)的寬度和高度不一致斟览。

int width = View.MeasureSpec.makeMeasureSpec(0,
        View.MeasureSpec.UNSPECIFIED);
int height = View.MeasureSpec.makeMeasureSpec(0,
        View.MeasureSpec.UNSPECIFIED);
view.measure(width, height);
view.getMeasuredWidth(); // 獲取寬度
view.getMeasuredHeight(); // 獲取高度

二毁腿、使用 ViewTreeObserver. OnPreDrawListener 監(jiān)聽事件
在視圖將要繪制時(shí)調(diào)用該監(jiān)聽事件,會被調(diào)用多次苛茂,因此獲取到視圖的寬度和高度后要移除該監(jiān)聽事件已烤。

view.getViewTreeObserver().addOnPreDrawListener(
        new ViewTreeObserver.OnPreDrawListener() {
 
    @Override
    public boolean onPreDraw() {
        view.getViewTreeObserver().removeOnPreDrawListener(this);
        view.getWidth(); // 獲取寬度
        view.getHeight(); // 獲取高度
        return true;
    }
});

三、使用 ViewTreeObserver. OnGlobalLayoutListener 監(jiān)聽事件
在布局發(fā)生改變或者某個(gè)視圖的可視狀態(tài)發(fā)生改變時(shí)調(diào)用該事件妓羊,會被多次調(diào)用胯究,因此需要在獲取到視圖的寬度和高度后執(zhí)行 remove 方法移除該監(jiān)聽事件。

view.getViewTreeObserver().addOnGlobalLayoutListener(
        new ViewTreeObserver.OnGlobalLayoutListener() {
 
    @Override
    public void onGlobalLayout() {
        if (Build.VERSION.SDK_INT >= 16) {
            view.getViewTreeObserver()
                    .removeOnGlobalLayoutListener(this);
        }
        else {
            view.getViewTreeObserver()
                    .removeGlobalOnLayoutListener(this);
        }
        view.getWidth(); // 獲取寬度
        view.getHeight(); // 獲取高度
    }
});

四躁绸、重寫 View 的 onSizeChanged 方法
在視圖的大小發(fā)生改變時(shí)調(diào)用該方法裕循,會被多次調(diào)用,因此獲取到寬度和高度后需要考慮禁用掉代碼涨颜。
該實(shí)現(xiàn)方法需要繼承 View费韭,且多次被調(diào)用,不建議使用庭瑰。

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
 
    view.getWidth(); // 獲取寬度
    view.getHeight(); // 獲取高度
}

五星持、重寫 View 的 onLayout 方法
該方法會被多次調(diào)用,獲取到寬度和高度后需要考慮禁用掉代碼弹灭。
該實(shí)現(xiàn)方法需要繼承 View督暂,且多次被調(diào)用揪垄,不建議使用。

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);
 
    view.getWidth(); // 獲取寬度
    view.getHeight(); // 獲取高度
}

六逻翁、使用 View.OnLayoutChangeListener 監(jiān)聽事件(API >= 11)
在視圖的 layout 改變時(shí)調(diào)用該事件饥努,會被多次調(diào)用,因此需要在獲取到視圖的寬度和高度后執(zhí)行 remove 方法移除該監(jiān)聽事件八回。

view.addOnLayoutChangeListener(
        new View.OnLayoutChangeListener() {
 
    @Override
    public void onLayoutChange(View v, int l, int t, int r, int b,
            int oldL, int oldT, int oldR, int oldB) {
        view.removeOnLayoutChangeListener(this);
        view.getWidth(); // 獲取寬度
        view.getHeight(); // 獲取高度
     }
});

七酷愧、使用 View.post() 方法
Runnable 對象中的方法會在 View 的 measure、layout 等事件完成后觸發(fā)缠诅。
UI 事件隊(duì)列會按順序處理事件溶浴,在 setContentView() 被調(diào)用后,事件隊(duì)列中會包含一個(gè)要求重新 layout 的 message管引,所以任何 post 到隊(duì)列中的 Runnable 對象都會在 Layout 發(fā)生變化后執(zhí)行士败。
該方法只會執(zhí)行一次,且邏輯簡單褥伴,建議使用谅将。

view.post(new Runnable() {
 
    @Override
    public void run() {
        view.getWidth(); // 獲取寬度
        view.getHeight(); // 獲取高度
    }
});

以上為轉(zhuǎn)載內(nèi)容,個(gè)人學(xué)習(xí)收藏記錄重慢,原文地址

下面是自己的學(xué)習(xí)記錄饥臂。
首先第一個(gè)方法,以前用過伤锚,確實(shí)不準(zhǔn)確擅笔,猜測是應(yīng)該是因?yàn)閰?shù)沒有用好,因?yàn)閰?shù)只使用UNSPECIFIED未指定的測量方式屯援,一般像Wrap_Content猛们,才是該測量方式。
這里貼一個(gè)比較好用的狞洋, AndroidUtilCode收藏的方法弯淘。

    public static int[] measureView(final View view) {
        ViewGroup.LayoutParams lp = view.getLayoutParams();
        if (lp == null) {
            lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT
            );
        }
        int widthSpec = ViewGroup.getChildMeasureSpec(0, 0, lp.width);
        int lpHeight = lp.height;
        int heightSpec;
        if (lpHeight > 0) {
            heightSpec = View.MeasureSpec.makeMeasureSpec(lpHeight, View.MeasureSpec.EXACTLY);
        } else {
            heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        }
        view.measure(widthSpec, heightSpec);
        return new int[]{view.getMeasuredWidth(), view.getMeasuredHeight()};
    }

然后是自己在做自定義view的時(shí)候,需要在一次add代碼創(chuàng)建的view吉懊,使用上面的方法無法獲得寬高庐橙,因?yàn)槲沂褂玫氖荢crollView。像在自定義中借嗽,加載一次布局态鳖,應(yīng)該選中最后一個(gè)post的方法最為使用。
另外還用的多的恶导,應(yīng)該是第三種方式浆竭,一般在外部使用,比如需要等待Recyclerview繪制完成后進(jìn)行的操作。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末邦泄,一起剝皮案震驚了整個(gè)濱河市删窒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌顺囊,老刑警劉巖肌索,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異特碳,居然都是意外死亡诚亚,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進(jìn)店門测萎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來亡电,“玉大人,你說我怎么就攤上這事硅瞧。” “怎么了恕汇?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵腕唧,是天一觀的道長。 經(jīng)常有香客問我瘾英,道長枣接,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任缺谴,我火速辦了婚禮但惶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘湿蛔。我一直安慰自己膀曾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布阳啥。 她就那樣靜靜地躺著添谊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪察迟。 梳的紋絲不亂的頭發(fā)上斩狱,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天,我揣著相機(jī)與錄音扎瓶,去河邊找鬼所踊。 笑死,一個(gè)胖子當(dāng)著我的面吹牛概荷,可吹牛的內(nèi)容都是我干的秕岛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼瓣蛀!你這毒婦竟也來了陆蟆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤惋增,失蹤者是張志新(化名)和其女友劉穎叠殷,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诈皿,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡林束,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了稽亏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片壶冒。...
    茶點(diǎn)故事閱讀 40,030評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖截歉,靈堂內(nèi)的尸體忽然破棺而出胖腾,到底是詐尸還是另有隱情,我是刑警寧澤瘪松,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布咸作,位于F島的核電站,受9級特大地震影響宵睦,放射性物質(zhì)發(fā)生泄漏记罚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一壳嚎、第九天 我趴在偏房一處隱蔽的房頂上張望桐智。 院中可真熱鬧,春花似錦烟馅、人聲如沸说庭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽口渔。三九已至,卻和暖如春穿撮,著一層夾襖步出監(jiān)牢的瞬間缺脉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工悦穿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留攻礼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓栗柒,卻偏偏與公主長得像礁扮,于是被迫代替她去往敵國和親知举。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評論 2 355

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