1. 程式人生 > >自己定義控件的onMeasure方法具體解釋

自己定義控件的onMeasure方法具體解釋

protected htm 靜態方法 進行 per idt pac width mil

在我們自己定義控件的時候可能你會用到onMeasure方法,以下就具體的給大家介紹一下這種方法:

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

我們自己定義一個類繼承View或者ViewGroup之後重寫onMeasure方法,我們看到這種方法傳遞進來兩個變量,這裏做一下解釋: widthMeasureSpec:推薦的寬度和寬度的計算模式
heightMeasureSpec:推薦的高度和高度的計算模式
這裏為什麽說是推薦的寬和高呢? 由於這種方法是測量的作用,顧名思義就是讓你測量一下你自身的寬和高,傳遞進來的變量僅僅是提供你作為參考,你依據這些參考值來計算你自身的寬和高!


那麽有的人又有疑問了,你說的上面兩個值的意思是推薦的寬和高以及響應的計算模式,可我怎麽就看到兩個值啊,你說的明明就是四個嘛? 這是由於一個變量裏面包括了兩個變量的值,所以我們須要對這兩個值進行操作,獲取相應的寬和高和相應的計算模式

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // 寬和高的計算模式
        int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
        int modeHeight = MeasureSpec.getMode(heightMeasureSpec);

        //真正的寬和高的數值
        int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
        int sizeHeigth = MeasureSpec.getSize(heightMeasureSpec);

        measureChildren(widthMeasureSpec, heightMeasureSpec);

        setMeasuredDimension(sizeWidth, sizeHeigth);

    }

能夠看到我們通過類MeasureSpec的靜態方法能夠獲取到對應的計算模式和寬和高
事實上計算模式就是你在布局文件裏寫的match_parent、wrap_content 而獲取出來的寬和高是當前的計算模式下父容器所能給你的最大寬和高 比方: 父容器320*480 你這個控件的寬和高用了match_parent 那麽這裏推薦你的寬和高就是320*480 計算模式就是一個match_parent常量:
ViewGroup.LayoutParams.MATCH_PARENT
技術分享
假如你用了wrap_content,那麽這裏推薦你的寬和高還是320*480 計算模式就是一個wrap_content常量:
ViewGroup.LayoutParams.WRAP_CONTENT
技術分享
為什麽推薦的寬和高和match_parent的時候一樣,由於父容器無法確定你的包裹內容的須要的寬和高詳細是多少,所以它僅僅能給你它最大的.所以這種方法計算的時候事實上說白了就是計算包裹內容的時候自身的大小,由於不管是match_parent還是寫死的大小父容器都能非常輕松的算出來你須要的大小,僅僅有在包裹的時候是不知道的,須要你自己計算,然後通知我,怎樣通知呢?


通過方法:setMeasureDimension(int,int)來告知,這裏面就是傳入你計算好的真正的寬和高.所以在不是包裹內容的時候父容器推薦你的寬和高是正確的,你無須計算,直接走父類的方法就可以,所以一般的解決方法就是以下這樣:

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // 寬和高的計算模式
        int modeWidth = MeasureSpec.getMode(widthMeasureSpec);
        int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
        //拿到父容器推薦的寬和高
        int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
        int sizeHeigth = MeasureSpec.getSize(heightMeasureSpec);
<span style="white-space:pre">	</span>//這裏測量每個孩子的寬和高
        if (modeWidth == MeasureSpec.ATMOST)
            //sizeWidth = 計算的值
        }
        if (modeHeight == MeasureSpec.ATMOST<span style="font-family: Arial, Helvetica, sans-serif;">)</span>
            //sizeHeigth = 計算的值
        }
        setMeasuredDimension(sizeWidth, sizeHeigth);
    }

好了今天如此具體的解說了這種方法的作用及其參數的作用,大家自己也去試試吧

自己定義控件的onMeasure方法具體解釋