android基礎(chǔ)-viewgroup的測量劫侧,布局园细,繪制

相關(guān)文章
android基礎(chǔ)-view的測量各吨,布局叛甫,繪制

知識點

  1. viewgroup的測量
  2. viewgroup的布局
  3. viewgroup的繪制

一、viewgroup的測量

viewgroup的作用主要用于管理子view谐丢,而在測量的時候可以分兩種情況

  • 當viewgroup的大小設(shè)置為 wrap_content的時候 : viewgroup就需要對子view進行遍歷爽航,以便于獲取每個子view的大小,從而來決定自身大小
  • 當viewgroup的大小設(shè)置為上述的其他模式的時候: 就會通過具體的大小來設(shè)置自身的大小

關(guān)于viewgroup遍歷子view去測量的方法乾忱,android中已經(jīng)幫我們封裝了兩個常用方法:
protected void measureChildren(int widthMeasureSpec, int heightMeasureSpec)
protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed)
從方法名和方法里面不難看出這兩個方法的區(qū)別讥珍,就是后者把子view的padding和margin也考慮了進去,不過他們最終調(diào)用的都是子view的view.measure(int wSpec,int hSpec)方法該方法回觸發(fā)子view的onMeasure方法

最后在測量子view之后饭耳,就要對自身大小做決定了串述,同樣是根據(jù)不同的測量模式來確定最終的大小执解,并且最后需要調(diào)用
protected final void setMeasuredDimension(int measuredWidth, int measuredHeight)
該方法來設(shè)置viewgroup的寬高

viewgroup的測量栗子如下:

   @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //測量子view
        measureChildren(widthMeasureSpec,heightMeasureSpec);

        int wModeSpec=MeasureSpec.getMode(widthMeasureSpec);
        int wSizeSpec=MeasureSpec.getSize(widthMeasureSpec);

        //這里只做了寬的測量寞肖,高度的測量也是類似的
        int resuletW=myMeasureWidth(wModeSpec,wSizeSpec);

        setMeasuredDimension(resuletW,heightMeasureSpec);
    }


    private  int myMeasureWidth(int specMode,int specSize){
        int result=0;
        if(specMode==MeasureSpec.EXACTLY){
            //精準模式直接賦值
            result=specSize;
        }else if(specMode==MeasureSpec.AT_MOST){
            //這里一般根據(jù)viewgroup的類型來做處理纲酗,比如framelayout,linearlayout這些類型
            //對于linearlayout類可以如下
            for (int i = 0; i < getChildCount(); i++) {
                View view = getChildAt(i);
                result += view.getMeasuredWidth();
            }

            //對于framelayout這種類型,我們只需取最大的就好
//            for (int i = 0; i < getChildCount(); i++) {
//                View view = getChildAt(i);
//                result = view.getMeasuredWidth() > result ? view.getMeasuredWidth() : result;
//            }
        }else {
            //剩余的這種模式就是沒限制大小的模式了新蟆,一般用于recyclerview這種可以擴展的布局形式
            //具體的測量方法就是看實際需求了
        }
        return result;
    }

二觅赊、viewgroup的布局

在自定義viewgroup的時候,我們必須重寫如下方法:

  @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

    }

該方法主要就是通知子view去設(shè)置他們的布局位置琼稻,之前android基礎(chǔ)-view的測量吮螺,布局,繪制的篇章也已經(jīng)詳細說明了view.layout方法的過程

   @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        // 子view數(shù)目
        int childCount = getChildCount();
        // 垂直擺放子view
        for (int i = 0;i<childCount;i++){
            View childView = getChildAt(i);
            int height = childView.getMeasuredHeight();
            childView.layout(l, i*height, r, t + (i+1)*height);
        }
      //這里擺放子view的設(shè)計也是根據(jù)實際需要帕翻,這里這做個簡單的例子
    }

三鸠补、viewgroup的繪制

viewgroup通知情況下不需要繪制,因為他本身就沒有需要繪制的東西嘀掸,如果不是指定了viewgroup的背景色紫岩,那么viewgroup的onDraw方法都不會被調(diào)用。但是睬塌,viewgroup會使用dispatchDraw()方法來繪制其子view泉蝌,其過程同樣是通過變遍歷所有的子view,并調(diào)用子view的繪制方法來完成繪制工作

    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
    }

注意對于viewgroup而言onDraw()先于dispatchDraw()執(zhí)行,用于本身控件的繪制,dispatchDraw()用于子控件的繪制揩晴,所以如果想對于viewgroup中繪制完子view之后在對其修改勋陪,我們可以在dispatchDraw調(diào)用surper方法之前做自己想要的繪制效果,這樣避免了被子view的覆蓋


總結(jié)

viewgroup的測量硫兰,布局诅愚,繪制,其實都只是用來管理和通知子view去具體實現(xiàn)劫映,可能最主要就是onLayout方法去定義子view的顯示位置呻粹,其他的核心都是在view中做處理的,所以先理解清楚view的顯示過程苏研,那么再來理解viewgroup的顯示過程等浊,就會容易理解許多

參考文章

《Android群英傳》?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市摹蘑,隨后出現(xiàn)的幾起案子筹燕,更是在濱河造成了極大的恐慌,老刑警劉巖衅鹿,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撒踪,死亡現(xiàn)場離奇詭異,居然都是意外死亡大渤,警方通過查閱死者的電腦和手機制妄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泵三,“玉大人耕捞,你說我怎么就攤上這事衔掸。” “怎么了俺抽?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵敞映,是天一觀的道長。 經(jīng)常有香客問我磷斧,道長振愿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任弛饭,我火速辦了婚禮冕末,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘侣颂。我一直安慰自己栓霜,他們只是感情好,可當我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布横蜒。 她就那樣靜靜地躺著胳蛮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪丛晌。 梳的紋絲不亂的頭發(fā)上仅炊,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天,我揣著相機與錄音澎蛛,去河邊找鬼抚垄。 笑死,一個胖子當著我的面吹牛谋逻,可吹牛的內(nèi)容都是我干的呆馁。 我是一名探鬼主播,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼毁兆,長吁一口氣:“原來是場噩夢啊……” “哼浙滤!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起气堕,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤纺腊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后茎芭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體揖膜,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年梅桩,在試婚紗的時候發(fā)現(xiàn)自己被綠了壹粟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡宿百,死狀恐怖趁仙,靈堂內(nèi)的尸體忽然破棺而出洪添,到底是詐尸還是另有隱情,我是刑警寧澤幸撕,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站外臂,受9級特大地震影響坐儿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜宋光,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一貌矿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧罪佳,春花似錦逛漫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蕾管,卻和暖如春枷踏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背掰曾。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工旭蠕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人旷坦。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓掏熬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親秒梅。 傳聞我的和親對象是個殘疾皇子旗芬,可洞房花燭夜當晚...
    茶點故事閱讀 43,562評論 2 349

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