1. 程式人生 > >Android獲取控制元件大小的方法

Android獲取控制元件大小的方法

在Android中很多時候都需要獲取到控制元件的大小,這樣對於佈局的計算有許多的幫助,比如一個GridView佈置成多少行多少列是需要提前知道自己允許的最大的高度和寬度才能計算,這樣就需要得到控制元件的大小。控制元件的大小是在View的measure的過程計算出來的。所有我們如果通過直接在onCreate()、onResume()等等方法中直接去取控制元件的大小是取不到的。而這裡面的原因是View的measure過程和Activity的生命週期是不同步的,也就是說無法保證Activity中的onCreate()等等執行的時候View的measure()已經執行了,如果此時還沒有執行肯定是得不到值的。 那麼到底有沒有得到控制元件大小的方法,答案肯定是有的。實現的方法分為兩大類: 1.View在執行measure()方法之後      這是很好理解的部分,等到View已經measure()了,我們當然能很方便的得到View的大小。      (1)Activity中的View.Callback中的onWindowFocusChanged(),在Activity中實現這個方法就可以獲取到空間的大小了。(PS:該方法會在Activity每次執行onResume()或者onPause()都執行)
public void onWindowFocusChanged(boolean hasFocus){
    if(hasFocus){
        int height = view.getHeight();
        int width = view.getWidth();
    }
}
         (2)使用ViewTreeObserver的很多的回撥介面。例如使用OnGlobalLayoutListener,當View樹的狀態發生變化或者View叔內部的View的可見性發生改變時。(PS:View樹改變的時候,onGlobalLayout會被呼叫多次)
@Override
protected void onStart() {
    super.onStart();
    textView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {  
        @Override
        public void onGlobalLayout() {
             int height = view.getHeight();
            int width = view.getWidth();                   
        }
    });
}
     (3)通過View的post()方法將一個runnable傳送到訊息佇列尾部,當該runnable執行的時候,此時的View已經初始化好了,可以得出View的大小。
@Override
protected void onStart() {
    super.onStart();
    textView.post(new Runnable() {
        @Override
        public void run() {
            int width = textView.getMeasuredWidth();
            int height = textView.getMeasuredHeight();
            System.out.println("Egos" + width + " " + height);
        }
    });
}
2.View在執行measure()方法之前 也就是說一定要在onCreate()等方法中來獲取控制元件的大小,可以知道View的measure過程是得到控制元件的大小,所以思路是可以通過手動measure來獲取控制元件的大小。但其實手動measure的方式得到控制元件的大小不一定每次都是正確的。需要根據佈局檔案中控制元件設定的大小的情況來討論。 a.match_parent 這種情況無法得到控制元件的大小,因為此時還需要考慮parent的佈局才能計算出該控制元件的大小。 b.固定的大小(dp/px) 例如:控制元件設定的是100dp
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(context.getResources().getDisplayMetrics().density *100,MeasureSpec.EXACTLY);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(context.getResources().getDisplayMetrics().density *100,MeasureSpec.EXACTLY);
view.measure(widthMeasureSpec,heightMeasureSpec);
int width = view.getMeasureWidth();
int height = view.getMeasureHeight();
c.wrap_content(網上得到的據說最正確的寫法)
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec((1 << 30) - 1, View.MeasureSpec.AT_MOST);
view.measure(widthMeasureSpec,heightMeasureSpec);
ps:方法來自網路和書籍,有什麼錯誤之處希望你