1. 程式人生 > >Activity中獲取view的高度和寬度方法

Activity中獲取view的高度和寬度方法

在activity中可以呼叫View.getWidth()、View.getHeight()、View.getMeasuredWidth() 、View.getgetMeasuredHeight()來獲得某個view的寬度或高度。
但是在onCreate()、onStrart()、onResume()方法中會返回0,這是應為當前activity所
代表的介面還沒顯示出來沒有新增到WindowPhone的DecorView上或要獲取的view沒
有被新增到DecorView上或者該View的visibility屬性為gone 或者該view的width或height真的為0
所以只有上述條件都不成立時才能得到非0的width和height

要獲取到的width和height為真實有效的有一下幾種方法

  • 在該View的事件回撥裡使用 這時候該view已經被顯示即被新增到DecorView上 如點選事件 觸控事件 焦點事件等
    View view=findViewById(R.id.tv);  
        view.setOnClickListener(new OnClickListener() {  

            @Override  
            public void onClick(View v) {  
                int width = v.getWidth();  
            }  
        });  
  • 在activity被顯示出來時即新增到了DecorView上時獲取寬和高如onWindowFocusChanged() 回撥方法
    @Override  
public void onWindowFocusChanged(boolean hasFocus) {  
        View iv1 = findViewById(R.id.iv1);  
        View iv2=findViewById(R.id.iv2);  
        String msg1="iv1' width:"+iv1.getWidth()+" height:"+iv1.getHeight
(); String msg2="iv2' width:"+iv2.getWidth()+" height:"+iv2.getHeight(); System.out.println(msg1); System.out.println(msg2); super.onWindowFocusChanged(hasFocus); }
  • 或在onResume方法最後開執行緒300毫秒左右後獲取寬和高 因為onResume執行完後300毫秒後 介面就顯示出來了
    view.postDelayed(new Runnable() {  

                @Override  
                public void run() {  
                    View iv1 = findViewById(R.id.iv1);  
                    View iv2=findViewById(R.id.iv2);  
                    String msg1="iv1' width:"+iv1.getWidth()+" height:"+iv1.getHeight()+"  measuredWidth:"+iv1.getMeasuredWidth()+"measuredHeight:"+iv1.getMeasuredHeight();  
                    String msg2="iv2' width:"+iv2.getWidth()+" height:"+iv2.getHeight()+"  measuredWidth:"+iv2.getMeasuredWidth()+"measuredHeight:"+iv2.getMeasuredHeight();  
                    i("onWindowFocusChanged() "+msg1);  
                    i("onWindowFocusChanged() "+msg2);  
                }  
            }, 300);  
  • 4.在onCreate()或onResume()等方法中需要獲取寬高時使用getViewTreeObserver().addOnGlobalLayoutListener()來添為view加回調在回撥裡獲得寬度或者高度獲取完後讓view刪除該回調
    view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {  

            @Override  
            public void onGlobalLayout() {  
                view.postDelayed(new Runnable() {  

                    @Override  
                    public void run() {  
                        View iv1 = findViewById(R.id.iv1);  
                        View iv2=findViewById(R.id.iv2);  
                        String msg1="iv1' width:"+iv1.getWidth()+" height:"+iv1.getHeight()+"  measuredWidth:"+iv1.getMeasuredWidth()+"measuredHeight:"+iv1.getMeasuredHeight();  
                        String msg2="iv2' width:"+iv2.getWidth()+" height:"+iv2.getHeight()+"  measuredWidth:"+iv2.getMeasuredWidth()+"measuredHeight:"+iv2.getMeasuredHeight();  
                        i("onWindowFocusChanged() "+msg1);  
                        i("onWindowFocusChanged() "+msg2);  
                    }  
                }, 300);  
            }  
        });  
  • 在視窗焦點發生變化時獲取寬高 onResume完後就會把介面渲染到視窗上 渲染完後將執行視窗焦點花生變化回撥 所以onResume到 onWindowFocusChanged為把介面渲染到視窗的時間
boolean measure;  
    View iv1;  
    View iv2;  
    @Override  
    public void onWindowFocusChanged(boolean hasFocus) {  
        super.onWindowFocusChanged(hasFocus);  
        if(hasFocus && !measure){  
            measure=true;  
            measure();  
        }  
    }  
    private void findViews(){  
        iv1 = findViewById(R.id.iv1);  
        iv2 =findViewById(R.id.iv2);  
    }  
    private void measure(){  
        String msg1="iv1' width:"+iv1.getWidth()+" height:"+iv1.getHeight();
        String msg2="iv2' width:"+iv2.getWidth()+" height:"+iv2.getHeight();
    }