Androidはコントロールの幅と高さのいくつかの方法を取得します

10738 ワード

onCreateでgetWidthとgetMeasuredWidthを直接呼び出すと、コントロールの幅と高さが得られないことを知っています.
理由は次のとおりです.
onCreateメソッドの実行が完了すると、定義したコントロールがメジャー化されるので、onCreateメソッドでview.getHeight()取得コントロールの高さまたは幅は0に違いない.それは自分がまだ測定されていないからだ.つまり、彼自身は自分がどれだけ高いか分からないが、あなたがこの時にそのサイズを取得するのは、きっとだめだ.
ProgressBarを例にとると、元のコントロールの幅を見てみましょう.
      <ProgressBar
                android:id="@+id/pb_number"
                style="?android:attr/progressBarStyleHorizontal"
                android:layout_width="match_parent"
                android:layout_height="25dp"

                 />
   
width630px
MeasuredWidth630px
Height50px
MeasuredHeight50px
  2
postwidth630px
postMeasuredWidth630px
postHeight50px
postMeasuredHeight50px          

まずgetWidthとgetMeasuredWidthの違いと両者の使用シーンについてお話しします
まず、getWidth()の公式説明を見てみましょう.
public final int getWidth ()

Added in API level 1
Return the width of the your view.

Returns
The width of your view, in pixels.

viewの幅を返して、詳しくは言わないで、getWidthソースコードを見ます:
 * Return the width of the your view. 
     * 
     * @return The width of your view, in pixels. 
     */  
    @ViewDebug.ExportedProperty(category = "layout")  
    public final int getWidth() {  
        return mRight - mLeft;  
    }

ソースコードから分かるように、getwidthは右座標から左座標を減算し、レイアウト後に座標を決定することができます.つまり、レイアウト後にgetwidthを呼び出して取得することができます.したがってgetWidth()で得られる幅は、ビューがレイアウトを設定した後のビュー全体の幅である.
getmeasuredwidthについては公式の説明を見てみましょう
public final int getMeasuredWidthAndState ()

Added in API level 11
Return the full width measurement information for this view as computed by the most recent call to measure(int, int). This result is a bit mask as defined byMEASURED_SIZE_MASK and MEASURED_STATE_TOO_SMALL. This should be used during measurement and layout calculations only. Use getWidth() to see how wide a view is after layout.

Returns
The measured width of this view as a bit mask.

得られたのはmeasure()メソッドを最近呼び出して測定した後に得られたViewの幅であり,測定とLayoutの計算にのみ使用すべきである.ソースコードを見てください.
/** 
 * Like {@link #getMeasuredWidthAndState()}, but only returns the 
 * raw width component (that is the result is masked by 
 * {@link #MEASURED_SIZE_MASK}). 
 * 
 * @return The raw measured width of this view. 
 */  
public final int getMeasuredWidth() {  
    return mMeasuredWidth & MEASURED_SIZE_MASK;  
}  

元の測定幅が得られた.したがってgetMeasuredWidth()は,View上のコンテンツを測定して得られるViewコンテンツが占める幅である.
親レイアウトのonLayout()メソッドまたはこのViewのonDraw()メソッドでmeasure(0,0)を呼び出す必要があることを前提とします.(measureのパラメータの値は自分で定義できます)、そうしないとgetWidth()と同じ結果になります.
両者の使用場面:
getMeasuredWidth:カスタムviewでonLayoutを書き換えるとき、layoutinflaterでviewを動的にロードした後、viewの元の幅を取得したいとき.
getWidth:一般的にviewがレイアウトされた後に現れ、幅を取得したい場合
以下から抜粋:http://blog.csdn.net/u011494050/article/details/39134161
次に、いくつかの取得方法について具体的に説明します.
No1:
int w = View.MeasureSpec.makeMeasureSpec(0,
                View.MeasureSpec.UNSPECIFIED);
        int h = View.MeasureSpec.makeMeasureSpec(0,
                View.MeasureSpec.UNSPECIFIED);
        imageView.measure(w, h);
        int height = imageView.getMeasuredHeight();
        int width = imageView.getMeasuredWidth();

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

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

この方法は2番目の方法とほぼ同じですが、グローバルなレイアウト変更リスナーなので、最もお勧めです.
まとめ:では、コントロールの幅を取得するには、その方法を使う必要がありますか?
  • メソッド1:他の2つのメソッドよりも1回多く計算、すなわち1回多くonMeasure()メソッドを呼び出す.このメソッドは簡単に見えるが、ターゲットコントロールの計算に時間がかかる場合(listViewなど)、使用を推奨しない.
  • メソッド2:そのコールバックメソッドは何度も呼び出され、TextViewをスライドするときに任意に呼び出されるので、使用は推奨されません.
  • 方法3:比較的に適当である.もちろん、実際に適用する場合は、実際の状況に応じて決める必要がある.

  • もっと簡単な方法を拡張してください.post:
                pbNumber.post(new Runnable() {
                        @Override
                        public void run() {
                            Log.v("tag", "postwidth"+pbNumber.getWidth()+"px");
                            Log.v("tag", "postMeasuredWidth"+pbNumber.getMeasuredWidth()+"px");
                            Log.v("tag", "postHeight"+pbNumber.getHeight()+"px");
                            Log.v("tag", "postMeasuredHeight"+pbNumber.getMeasuredHeight()+"px");
    
                        }
                    });

    View.post()この方法は一般的に何に使いますか?
    私が最も深く感じているのは2つの役割です.
  • onCreate()メソッドでviewを呼び出すことはよく知られています.getHeight()は0を返しますが、
  •   view.post(new Runnable() {
                @Override
                public void run() {
                     MainApp.showToastMsg("" + view.getHeight());
                }
            });
    

    彼の高さを手に入れます
  • 用View.postDelayed()メソッドは、一定期間にわたってviewを複数回クリックして複数回の不要なクリックイベントをトリガーすることを防止する:
  •  view.setEnabled(false);
     view.postDelayed(new Runnable() {
                @Override
                public void run() {
                   view.setEnabled(true); 
                }
            },300);

    怠け者の私は、迷わずviewを選びました.postメソッド.参考:以上の3つの方法で説明します.http://blog.csdn.net/johnny901114/article/details/7839512 view.post方式の解釈https://segmentfault.com/q/1010000004304827/a-1020000004332087
    http://androidperformance.com/2015/12/29/Android%E5%BA%94%E7%94%A8%E5%90%AF%E5%8A%A8%E4%BC%98%E5%8C%96-%E4%B8%80%E7%A7%8DDelayLoad%E7%9A%84%E5%AE%9E%E7%8E%B0%E5%92%8C%E5%8E%9F%E7%90%86-%E4%B8%8B%E7%AF%87.html