web-dev-qa-db-ja.com

getmeasuredheight()およびgetmeasuredwidth()は、View.measure()の後に0を返します

view.measure()定数次元を使用してViewを測定した後、getMeasuredHeight()およびgetMeasureWidth()は0を返します。

layout_view.xml、ビューを作成するためにインフレートされるレイアウト

<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android" 
    Android:layout_width="100dp"
    Android:layout_height="100dp">
</FrameLayout>

寸法を測定する関数

public void measureView(Context context){
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.layout_view,null,false);

    view.measure( View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);

    Log.d(TAG,"Error width : " + view.getMeasuredWidth());
    Log.d(TAG,"Error heeght : " + view.getMeasuredHeight());

}
16
SathMK

view.getMeasuredWidth()またはonCreate()onCreateView()を呼び出すとき、viewはまだ描画されていません。したがって、リスナーを追加する必要があり、viewが描画されているときにコールバックを取得します。ちょうど私のコードでこれのように:

_final ViewTreeObserver vto = view.getViewTreeObserver();
if (vto.isAlive()) {
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            int viewWidth = view.getMeasuredWidth();
            // handle viewWidth here...

            if (Build.VERSION.SDK_INT < 16) {
                vto.removeGlobalOnLayoutListener(this);
            } else {
                vto.removeOnGlobalLayoutListener(this);
            }
        }
    });
}
_

注:パフォーマンスを向上させるためにリスナーを削除してください!

リスナーを削除するためにvto.removeOnGlobalLayoutListener(this)を呼び出さないでください。次のように呼び出します。

_vto.getViewTreeObserver()
_
10
Francis Shi

onCreate()でビューを測定していますか?ビューはまだ描画されていません。ビューを描画した後、測定できるようになるまで待つ必要があります。

これに対する簡単な解決策は、ランナブルをレイアウトにポストすることです。ランナブルは、レイアウトが行われた後に実行されます。

詳細については この投稿を参照

編集変更を試みます

view.measure( View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);

view.measure( View.MeasureSpec.EXACTLY, View.MeasureSpec.EXACTLY);
6
Giru Bhai

この方法を試してください。これが問題の解決に役立つことを願っています。

view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
   @Override
   public void onGlobalLayout() {
     int width = view.getMeasuredWidth();
     int height = view.getMeasuredHeight();

   }
});
4
Haresh Chhelana

測定されたビューの可視性が「なし」に設定されている場合、測定は0を返します。すべてをコードから表示、測定、および「なし」に戻すことができます。

1
Radu Simionescu

measure呼び出しで_View.MeasureSpec.*_を直接使用することはできません。代わりに、最初にmakeMeasureSpec()を使用し、次にそれを使用してmeasure()を呼び出します。

_final int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT/*can be match_parent or some exact value*/, View.MeasureSpec.UNSPECIFIED);
final int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT/*can be match_parent or some exact value*/, View.MeasureSpec.UNSPECIFIED);
view.measure(widthMeasureSpec, heightMeasureSpec);
_
1
M-WaJeEh

_onCreate/onCreateView_およびその他のイベントでgetViewTreeObserverを使用できます。

_fun setGlobalLayoutListener(view: View, method: () -> Unit) {
    val vto1 = view.viewTreeObserver
    if (vto1.isAlive) {
        vto1.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                val vto2 = view.viewTreeObserver
                if (vto2.isAlive) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                        vto2.removeOnGlobalLayoutListener(this)
                    } else {
                        @Suppress("DEPRECATION")
                        vto2.removeGlobalOnLayoutListener(this)
                    }
                    // Your actions are here:
                    method()
                }
            }
        })
    }
}
_

そして、それを呼び出します:setGlobalLayoutListener(view) {updateUI(view)}

私も試しました

_view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
_

次に、onCreateView()/onViewCreated()で_view.control.measuredWidth_を呼び出します。しかし、一部のエミュレーター(API 19)では、誤った結果が返されました。

0
CoolMind

ImageViewでこの問題が発生した場合に備えて:

ImageViewに「Android:src」が設定されていない場合(つまり、動的に変更する場合)、getMeasuredWidth/Heightから常にゼロが返されることに気付きました。

簡単な回避策は、ビューのプレースホルダーを設定することです。