<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆雜記

       :: 首頁 :: 新隨筆 ::  ::  :: 管理 ::

    有時,Android系統控件無法滿足我們的需求,因此有必要自定義View。具體方法參見官方開發文檔:http://developer.android.com/guide/topics/ui/custom-components.html


    一般來說,自定義控件都會去重寫View的onMeasure方法,因為該方法指定該控件在屏幕上的大小。

    protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)

    onMeasure傳入的兩個參數是由上一層控件傳入的大小,有多種情況,重寫該方法時需要對計算控件的實際大小,然后調用setMeasuredDimension(int, int)設置實際大小。


    onMeasure傳入的widthMeasureSpec和heightMeasureSpec不是一般的尺寸數值,而是將模式和尺寸組合在一起的數值。我們需要通過int mode = MeasureSpec.getMode(widthMeasureSpec)得到模式,用int size = MeasureSpec.getSize(widthMeasureSpec)得到尺寸。


    mode共有三種情況,取值分別為MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST。


    MeasureSpec.EXACTLY是精確尺寸,當我們將控件的layout_width或layout_height指定為具體數值時如andorid:layout_width="50dip",或者為FILL_PARENT是,都是控件大小已經確定的情況,都是精確尺寸。


    MeasureSpec.AT_MOST是最大尺寸,當控件的layout_width或layout_height指定為WRAP_CONTENT時,控件大小一般隨著控件的子空間或內容進行變化,此時控件尺寸只要不超過父控件允許的最大尺寸即可。因此,此時的mode是AT_MOST,size給出了父控件允許的最大尺寸。


    MeasureSpec.UNSPECIFIED是未指定尺寸,這種情況不多,一般都是父控件是AdapterView,通過measure方法傳入的模式。


    因此,在重寫onMeasure方法時要根據模式不同進行尺寸計算。下面代碼就是一種比較典型的方式:

    @Override    
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {    
        setMeasuredDimension(getMeasuredLength(widthMeasureSpec, true), getMeasuredLength(heightMeasureSpec, false));    
    }    
        
        
    private int getMeasuredLength(int length, boolean isWidth) {    
        int specMode = MeasureSpec.getMode(length);    
        int specSize = MeasureSpec.getSize(length);    
        int size;    
        int padding = isWidth ? getPaddingLeft() + getPaddingRight()    
                : getPaddingTop() + getPaddingBottom();    
        if (specMode == MeasureSpec.EXACTLY) {    
            size = specSize;    
        } else {    
            size = isWidth ? padding + mWave.length / 4 : DEFAULT_HEIGHT    
                    + padding;    
            if (specMode == MeasureSpec.AT_MOST) {    
                size = Math.min(size, specSize);    
            }    
        }    
        return size;    
    }  

    posted on 2012-03-15 19:18 天宇恒星 閱讀(30318) 評論(2)  編輯  收藏 所屬分類: Android

    評論

    # re: Android中自定義View的MeasureSpec使用 2013-02-01 11:53 jeremy_sky
    你好。mode共有三種情況,取值分別為MeasureSpec.UNSPECIFIED, MeasureSpec.EXACTLY, MeasureSpec.AT_MOST。既然三種模式對應不同的數值,那么為什么在源碼中需要這個模式屬性呢?比如:(Linearlayout.java 方法 measureVertical(int widthMeasureSpec, int heightMeasureSpec)部分源碼 )
    if (heightMode == MeasureSpec.EXACTLY && lp.height == 0 && lp.weight > 0) {
    final int totalLength = mTotalLength;
    mTotalLength = Math.max(totalLength, totalLength + lp.topMargin + lp.bottomMargin);
    } else {
    int oldHeight = Integer.MIN_VALUE;

    if (lp.height == 0 && lp.weight > 0) {
    oldHeight = 0;
    lp.height = LayoutParams.WRAP_CONTENT;
    }
    ...
    }
    能幫我解釋一下么?(主要是代碼沒看懂~~~)

      回復  更多評論
      

    # re: Android中自定義View的MeasureSpec使用 2014-12-01 19:53 渣渣
    heightMode == MeasureSpec.EXACTLY && lp.height == 0 && lp.weight > 0這個很明顯是要判斷權重weight,哎寫自定義控件確實是個麻煩事,要考慮寬高,還要考慮padding,weight。  回復  更多評論
      

    主站蜘蛛池模板: 国产AV无码专区亚洲AVJULIA| 亚洲国产成人精品91久久久| 久久精品国产亚洲沈樵| 久青草国产免费观看| 亚洲中文字幕无码专区| 免费国产va视频永久在线观看| 四虎成人精品在永久免费| 日日摸日日碰夜夜爽亚洲| 午夜国产羞羞视频免费网站| 免费国产草莓视频在线观看黄| 亚洲色偷偷狠狠综合网| a成人毛片免费观看| 亚洲视频精品在线| 国产成人精品免费视频大| 国产精品久久亚洲不卡动漫| 午夜a级成人免费毛片| AV激情亚洲男人的天堂国语| 亚洲国产成人久久综合野外| 免费网站观看WWW在线观看| 亚洲va久久久噜噜噜久久狠狠 | a毛片免费全部播放完整成| 国产成人无码综合亚洲日韩| 一区二区三区四区免费视频 | 亚洲一级毛片免费在线观看| 好男人看视频免费2019中文| 国产精品亚洲综合网站| 亚洲人成伊人成综合网久久久| 91av免费观看| 国产精品亚洲天堂| 亚洲av中文无码乱人伦在线播放 | 亚洲精品国产免费| 天天看片天天爽_免费播放| 四虎国产精品成人免费久久| 亚洲AV无码成人网站久久精品大| 免费三级毛片电影片| 老司机福利在线免费观看| 亚洲国产人成在线观看69网站| 成年女人午夜毛片免费视频| 国产免费久久久久久无码| 亚洲欧洲日本精品| 亚洲视频在线免费|