AndroidはどのようにしてViewの幅と高さを正確に獲得しますか?


前言
PopupWindowのshowAsDropDown()メソッドを設定場合は、相対コントロールの底と揃えたいのでyのオフセットで負の高さに設定したいのですが、oncreate()でviewを利用します.getWidth()またはview.getHeiht()はviewの幅と高さを取得し、彼らの値は0です!oncreate()メソッドを呼び出すと、インタフェースが非表示になり、メモリロードコンポーネントが描画されていないため、サイズを取得できません.では、コンポーネントを描画する前に、コンポーネントのサイズを取得するにはどうすればいいのでしょうか.
方法
方法1:
//    
int width =View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
int height =View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
view.measure(width,height);
int height=view.getMeasuredHeight(); 
int width=view.getMeasuredWidth();

この方法は簡単です.私たちが自分で測ることです.
方法2:
//           
ViewTreeObserver vto =view.getViewTreeObserver(); 
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
   @Override
   public boolean onPreDraw() { 
       vto.removeOnPreDrawListener(this);
       int height =view.getMeasuredHeight(); 
       int width =view.getMeasuredWidth();   
       return true;   
   }
});

この方法では、ViewTreeObserverのリスニングコールバックを登録する必要があります.このリスニングコールバックは、図面を専門にリスニングしています.図面をリスニングする以上、測定値を取得することができます.同時に、リスニングのたびにremoveの前のリスニングを行い、リスニングを繰り返すことを避けることができます.
方法3:
//        
ViewTreeObserver vto = view.getViewTreeObserver();  
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener(){ 
    @Override 
    public void onGlobalLayout() {     
        int height =view.getHeight(); 
        int width =view.getWidth();
        view.getViewTreeObserver().removeGlobalOnLayoutListener(this);  
    } 
});

この方法は2番目の方法とほぼ同じですが、グローバルなレイアウト変更リスナーなので、最もお勧めです.