Reputation: 1171
After measuring a View
with a constant dimensions with view.measure()
, the getMeasuredHeight()
and getMeasureWidth()
is returning 0.
layout_view.xml, layout which is inflated to create the view
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="100dp">
</FrameLayout>
function which measures the dimensions
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 height : " + view.getMeasuredHeight());
}
Upvotes: 24
Views: 35735
Reputation: 28783
You can use getViewTreeObserver
in onCreate/onCreateView
and other events.
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()
}
}
})
}
}
And call it: setGlobalLayoutListener(view) {updateUI(view)}
.
I also tried
view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
and then called view.control.measuredWidth
in onCreateView()/onViewCreated()
. But in some emulators (API 19) it returned wrong results.
Upvotes: 0
Reputation: 17284
You can not use View.MeasureSpec.*
directly in measure
call. Instead first makeMeasureSpec()
and then use it to invoke 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);
Upvotes: 0
Reputation: 395
When you call view.getMeasuredWidth()
in onCreate()
or onCreateView()
, the view
has not been drawn yet. So you need to add a listener and will get a callback when the view
is being drawn. Just like this in my code:
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);
}
}
});
}
NOTE: Remove the listener for better performance!
Don't call vto.removeOnGlobalLayoutListener(this)
to remove the listener. Call it like this:
vto.getViewTreeObserver()
Upvotes: 17
Reputation: 1
Just in case someone was experiencing this problem with ImageView:
I noticed that if your ImageView doesn't have "android:src" set (i.e. you change it dynamically) it will always return zero from getMeasuredWidth/Height.
A simple workaround would be to set a placeholder for view.
Upvotes: 0
Reputation: 4676
if your measured view has visibility set to gone, measuring will return 0. You can set it to visible, measure, and then set back to gone, all from code.
Upvotes: 1
Reputation: 14398
Are you measuring the view in onCreate()
. The view isn't drawn yet. You have to wait until a time after the view is drawn before you can measure it.
Simple solution for this is to post a runnable to the layout. The runnable will be executed after the layout has happened.
For more info See this post
Edit try to change
view.measure( View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
to
view.measure( View.MeasureSpec.EXACTLY, View.MeasureSpec.EXACTLY);
Upvotes: 7
Reputation: 24848
Try this way,hope this will help you to solve your problem.
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
}
});
Upvotes: 4