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());
}
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()
_
onCreate()
でビューを測定していますか?ビューはまだ描画されていません。ビューを描画した後、測定できるようになるまで待つ必要があります。
これに対する簡単な解決策は、ランナブルをレイアウトにポストすることです。ランナブルは、レイアウトが行われた後に実行されます。
詳細については この投稿を参照
編集変更を試みます
view.measure( View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
に
view.measure( View.MeasureSpec.EXACTLY, View.MeasureSpec.EXACTLY);
この方法を試してください。これが問題の解決に役立つことを願っています。
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
}
});
測定されたビューの可視性が「なし」に設定されている場合、測定は0を返します。すべてをコードから表示、測定、および「なし」に戻すことができます。
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);
_
_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)では、誤った結果が返されました。
ImageViewでこの問題が発生した場合に備えて:
ImageViewに「Android:src」が設定されていない場合(つまり、動的に変更する場合)、getMeasuredWidth/Heightから常にゼロが返されることに気付きました。
簡単な回避策は、ビューのプレースホルダーを設定することです。