測(cè)量View(三):獲得測(cè)量寬高及真實(shí)寬高

測(cè)量View(一):創(chuàng)建View并測(cè)量 http://www.reibang.com/p/4fb206b947ee
測(cè)量View(二):測(cè)量寬高及真實(shí)寬高 http://www.reibang.com/p/18540e62ae3a

現(xiàn)在我們可以解決在 測(cè)量View(一):創(chuàng)建View并測(cè)量 中的問題了

調(diào)用View的measure 及 layout方法便可獲得測(cè)量寬高及真實(shí)寬高

方法1:View.post()

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRoot = (LinearLayout) findViewById(R.id.root);

        view = new View(this);
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(300, 300);
        view.setLayoutParams(layoutParams);

        //將View加到根視圖中
        mRoot.addView(view);

        int width = view.getWidth();
        int height = view.getHeight();
        int measuredWidthAndState = view.getMeasuredWidthAndState();
        int measuredWidth = view.getMeasuredWidth();
        int measuredHeight = view.getMeasuredHeight();
        int measuredHeightAndState = view.getMeasuredHeightAndState();
    }
Paste_Image.png

結(jié)果怎么還是0.

查看addView()代碼:

public void addView(View child, int index, LayoutParams params) {
       ...
        requestLayout();
       ...
    }

之前學(xué)習(xí)自定義View時(shí)良蛮,認(rèn)為父布局requestLayout后會(huì)重新遍歷子布局的measure及l(fā)ayout方法
既然調(diào)用了measure, layout方法其垄,為何獲取不到測(cè)量的寬高只锭,真實(shí)的寬高。

以下這篇分析了requestLayout方法
http://www.reibang.com/p/effe9b4333de
簡(jiǎn)單說就是調(diào)用requestLayout后,遍歷子布局的操作是在分線程進(jìn)行的。

知道了原因,上代碼

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRoot = (LinearLayout) findViewById(R.id.root);

        view = new View(this);
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(300, 300);
        view.setLayoutParams(layoutParams);

        mRoot.addView(view);

        view.post(new Runnable() {
            @Override
            public void run() {
                int width = view.getWidth();
                int height = view.getHeight();
                int measuredWidthAndState = view.getMeasuredWidthAndState();
                int measuredWidth = view.getMeasuredWidth();
                int measuredHeight = view.getMeasuredHeight();
                int measuredHeightAndState = view.getMeasuredHeightAndState();
            }
        });
  }
Paste_Image.png

問題解決

方法2:onWindowFocusChanged()

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRoot = (LinearLayout) findViewById(R.id.root);

        view = new View(this);
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(300, 300);
        view.setLayoutParams(layoutParams);
        mRoot.addView(view);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        int width = view.getWidth();
        int height = view.getHeight();
        int measuredWidthAndState = view.getMeasuredWidthAndState();
        int measuredWidth = view.getMeasuredWidth();
        int measuredHeight = view.getMeasuredHeight();
        int measuredHeightAndState = view.getMeasuredHeightAndState();
    }

onWindowFocusChanged()方法在View的onSizeChanged()后調(diào)用冬耿。此時(shí)View的寬高都已確認(rèn)
此時(shí)獲得寬高肯定沒問題。

Paste_Image.png

方法3:onClick()中獲得寬高

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRoot = (LinearLayout) findViewById(R.id.root);

        view = new View(this);
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(300, 300);
        view.setLayoutParams(layoutParams);
        mRoot.addView(view);

        mRoot.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int width = view.getWidth();
                int height = view.getHeight();
                int measuredWidthAndState = view.getMeasuredWidthAndState();
                int measuredWidth = view.getMeasuredWidth();
                int measuredHeight = view.getMeasuredHeight();
                int measuredHeightAndState = view.getMeasuredHeightAndState();
            }
        });
    }
Paste_Image.png

沒毛病萌壳,以上三種方法都是打時(shí)間差

方法4 網(wǎng)上有一種方法:手動(dòng)measure()

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRoot = (LinearLayout) findViewById(R.id.root);

        view = new View(this);
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(300, 300);
        view.setLayoutParams(layoutParams);
        mRoot.addView(view);
        view.measure(0, 0);
        int width = view.getWidth();
        int height = view.getHeight();
        int measuredWidthAndState = view.getMeasuredWidthAndState();
        int measuredWidth = view.getMeasuredWidth();
        int measuredHeight = view.getMeasuredHeight();
        int measuredHeightAndState = view.getMeasuredHeightAndState();
    }

這里的mesure(0, 0)相當(dāng)于:

        int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);//0
        int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);//0
        view.measure(widthSpec, heightSpec);

但是sorry日月,結(jié)果還是0

Paste_Image.png

查看原代碼:調(diào)用了View的onMeasure()方法

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec));
    }

getSuggestedMinimumWidth()

    protected int getSuggestedMinimumWidth() {
        return (mBackground == null) ? mMinWidth : max(mMinWidth, mBackground.getMinimumWidth());
    }

getSuggestedMinimumHeight()

    protected int getSuggestedMinimumHeight() {
        return (mBackground == null) ? mMinHeight : max(mMinHeight, mBackground.getMinimumHeight());

    }

以上發(fā)現(xiàn)View的寬高與mMinWidth 及 背景的寬高有關(guān)系

修改代碼:

設(shè)置最小寬高
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRoot = (LinearLayout) findViewById(R.id.root);

        view = new View(this);
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(300, 300);
        view.setLayoutParams(layoutParams);

        view.setMinimumWidth(100);
        view.setMinimumHeight(200);

        mRoot.addView(view);

        view.measure(0, 0);
        int width = view.getWidth();
        int height = view.getHeight();
        int measuredWidthAndState = view.getMeasuredWidthAndState();
        int measuredWidth = view.getMeasuredWidth();
        int measuredHeight = view.getMeasuredHeight();
        int measuredHeightAndState = view.getMeasuredHeightAndState();
    }
Paste_Image.png
設(shè)置背景圖片

(1)png圖片

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRoot = (LinearLayout) findViewById(R.id.root);

        view = new View(this);
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(300, 300);
        view.setLayoutParams(layoutParams);

        //drawable-mdpi中的png圖片48 * 48
        view.setBackgroundResource(R.drawable.ic_launcher);
        mRoot.addView(view); //加不加都行

        Drawable background = view.getBackground();
        int intrinsicWidth = background.getIntrinsicWidth();
        int intrinsicHeight = background.getIntrinsicHeight();
       

        view.measure(0, 0);
        int width = view.getWidth();
        int height = view.getHeight();
        int measuredWidthAndState = view.getMeasuredWidthAndState();
        int measuredWidth = view.getMeasuredWidth();
        int measuredHeight = view.getMeasuredHeight();
        int measuredHeightAndState = view.getMeasuredHeightAndState();
    }
Paste_Image.png

(2)xml自定義Drawable

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRoot = (LinearLayout) findViewById(R.id.root);

        view = new View(this);
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(300, 300);
        view.setLayoutParams(layoutParams);

//        drawable-mdpi中自定義的GradientDrawable
//        <?xml version="1.0" encoding="utf-8"?>
//        <shape xmlns:android="http://schemas.android.com/apk/res/android">
//               <solid android:color="@color/colorPrimary" />
//               <size
//                       android:width="100dp"
//                       android:height="100dp" />
//        </shape>
        view.setBackgroundResource(R.drawable.bitmap);
        mRoot.addView(view); //加不加都行

        Drawable background = view.getBackground();
        int intrinsicWidth = background.getIntrinsicWidth();
        int intrinsicHeight = background.getIntrinsicHeight();
        
        view.measure(0, 0);
        int width = view.getWidth();
        int height = view.getHeight();
        int measuredWidthAndState = view.getMeasuredWidthAndState();
        int measuredWidth = view.getMeasuredWidth();
        int measuredHeight = view.getMeasuredHeight();
        int measuredHeightAndState = view.getMeasuredHeightAndState();
    }
Paste_Image.png

(3)代碼定義ShapeDrawable

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRoot = (LinearLayout) findViewById(R.id.root);

        view = new View(this);
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(300, 300);
        view.setLayoutParams(layoutParams);

        ShapeDrawable drawable = new ShapeDrawable();
        drawable.setIntrinsicHeight(100);
        drawable.setIntrinsicWidth(100);

        view.setBackgroundDrawable(drawable);
        mRoot.addView(view);//加不加都可以

        Drawable background = view.getBackground();
        int intrinsicWidth = background.getIntrinsicWidth();
        int intrinsicHeight = background.getIntrinsicHeight();
       
        view.measure(0, 0);
        int width = view.getWidth();
        int height = view.getHeight();
        int measuredWidthAndState = view.getMeasuredWidthAndState();
        int measuredWidth = view.getMeasuredWidth();
        int measuredHeight = view.getMeasuredHeight();
        int measuredHeightAndState = view.getMeasuredHeightAndState();
    }
Paste_Image.png

測(cè)試手機(jī)當(dāng)前的density為3.0 densityDpi為480

手動(dòng)測(cè)量得到測(cè)量的寬高袱瓮,而真實(shí)的寬高都是0,沒毛病

注意:所有的View在measure()時(shí)都與最小寬高及背景有關(guān)嗎?答案是否.要看具體的View中onMeasure()方法的定義

以上measure方法可以將View加到主布局中,也可以不加,都可以獲得測(cè)量寬高

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末爱咬,一起剝皮案震驚了整個(gè)濱河市尺借,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌精拟,老刑警劉巖燎斩,帶你破解...
    沈念sama閱讀 212,332評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蜂绎,居然都是意外死亡栅表,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,508評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門师枣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來怪瓶,“玉大人,你說我怎么就攤上這事践美∠捶。” “怎么了找岖?”我有些...
    開封第一講書人閱讀 157,812評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)敛滋。 經(jīng)常有香客問我许布,道長(zhǎng),這世上最難降的妖魔是什么绎晃? 我笑而不...
    開封第一講書人閱讀 56,607評(píng)論 1 284
  • 正文 為了忘掉前任蜜唾,我火速辦了婚禮,結(jié)果婚禮上箕昭,老公的妹妹穿的比我還像新娘灵妨。我一直安慰自己,他們只是感情好落竹,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,728評(píng)論 6 386
  • 文/花漫 我一把揭開白布泌霍。 她就那樣靜靜地躺著,像睡著了一般述召。 火紅的嫁衣襯著肌膚如雪朱转。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,919評(píng)論 1 290
  • 那天积暖,我揣著相機(jī)與錄音藤为,去河邊找鬼。 笑死夺刑,一個(gè)胖子當(dāng)著我的面吹牛缅疟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播遍愿,決...
    沈念sama閱讀 39,071評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼存淫,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了沼填?” 一聲冷哼從身側(cè)響起桅咆,我...
    開封第一講書人閱讀 37,802評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎坞笙,沒想到半個(gè)月后岩饼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,256評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡薛夜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,576評(píng)論 2 327
  • 正文 我和宋清朗相戀三年籍茧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片却邓。...
    茶點(diǎn)故事閱讀 38,712評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡硕糊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情简十,我是刑警寧澤檬某,帶...
    沈念sama閱讀 34,389評(píng)論 4 332
  • 正文 年R本政府宣布,位于F島的核電站螟蝙,受9級(jí)特大地震影響恢恼,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜胰默,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,032評(píng)論 3 316
  • 文/蒙蒙 一场斑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧牵署,春花似錦漏隐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至取具,卻和暖如春脖隶,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背暇检。 一陣腳步聲響...
    開封第一講書人閱讀 32,026評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工产阱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人块仆。 一個(gè)月前我還...
    沈念sama閱讀 46,473評(píng)論 2 360
  • 正文 我出身青樓构蹬,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親悔据。 傳聞我的和親對(duì)象是個(gè)殘疾皇子怎燥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,606評(píng)論 2 350

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