getHeight returns 0 for all Android UI objects

JavaAndroidAndroid LayoutAndroid Framelayout

Java Problem Overview


I'm building a UI, and it's all static defined in the XML. All of it has weights all over the place, and while it looks right, I wanted to see that things actually have the right height and all. The problem is that no matter where I call .getHeight() for my format layout I got 0. I tried in both onCreate() and onStart(). Same thing. Happens for all UI objects too. Any idea?

package com.app.conekta;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.Toast;

public class Conekta extends Activity {
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
	}

	@Override
	public void onStart() {

		super.onStart();
		
		
	}
	
	@Override
	public void onResume() {
		super.onResume();
		
		FrameLayout fl1 = (FrameLayout) findViewById(R.id.headerFrameLayout);
		FrameLayout fl2 = (FrameLayout) findViewById(R.id.footerFrameLayout);
		Button b=(Button) findViewById(R.id.searchButton);
		
		Log.d("CONEKTA", String.valueOf(b.getHeight()));
		
	}
}

XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >



    <FrameLayout
        android:id="@+id/headerFrameLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.05"
        android:background="#597eAA" >

        <ImageView
            android:id="@+id/logoImage"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="#7ba1d1"
            android:src="@drawable/logo_conekta" />
    </FrameLayout>

    <LinearLayout
        android:id="@+id/bodyLinearLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.7"
        android:background="#f3f3f3"
        android:orientation="horizontal" >

        <FrameLayout
            android:id="@+id/leftBlankFrameLayout"
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:layout_weight="0.15"
            android:background="#f3f3f3" >
        </FrameLayout>

        <LinearLayout
            android:id="@+id/centerVerticalLayout"
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:layout_weight="0.7"
            android:orientation="vertical" >

            <FrameLayout
                android:id="@+id/topCenterFrameLayout"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="0.35" >
            </FrameLayout>

            <TextView
                android:id="@+id/venueLabel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="0.025"
                android:text="What are you looking for?"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="#000000" />

            <EditText
                android:id="@+id/venueTextField"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="0.025" >

                <requestFocus />
            </EditText>

            <FrameLayout
                android:id="@+id/middleCenterFrameLayout"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="0.05" >
            </FrameLayout>

            <TextView
                android:id="@+id/locationLabel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="0.025"
                android:text="Where?"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="#000000" />

            <AutoCompleteTextView
                android:id="@+id/locationTextField"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="0.025"
                android:text="" />

            <LinearLayout
                android:id="@+id/buttonLinearLayout"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="0.05"
                android:background="#f3f3f3"
                android:orientation="horizontal" >

                <FrameLayout
                    android:id="@+id/leftButtonLinearLayout"
                    android:layout_width="wrap_content"
                    android:layout_height="fill_parent"
                    android:layout_weight="0.1" >
                </FrameLayout>

                <Button
                    android:id="@+id/searchButton"
                    android:layout_width="wrap_content"
                    android:layout_height="fill_parent"
                    android:layout_weight="0.8"
                    android:background="#6fa8dc"
                    android:text="Search" />

                <FrameLayout
                    android:id="@+id/rightButtonLinearLayout"
                    android:layout_width="wrap_content"
                    android:layout_height="fill_parent"
                    android:layout_weight="0.1" >
                </FrameLayout>
            </LinearLayout>

            <FrameLayout
                android:id="@+id/bottomCenterFrameLayout"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="0.35" >
            </FrameLayout>
        </LinearLayout>

        <FrameLayout
            android:id="@+id/rightBlankFrameLayout"
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:layout_weight="0.15"
            android:background="#f3f3f3" >
        </FrameLayout>
    </LinearLayout>

    <FrameLayout
        android:id="@+id/footerFrameLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.15"
        android:background="#7ba1d1" >
    </FrameLayout>

</LinearLayout>

Java Solutions


Solution 1 - Java

It's 0 because in both onCreate and onStart, the view hasn't actually been drawn yet. You can get around this by listening for when the view is actually drawn:

final TextView tv = (TextView)findViewById(R.id.venueLabel);
final ViewTreeObserver observer= tv.getViewTreeObserver();
       observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
              tv.getHeight()
              observer.removeGlobalOnLayoutListener(this);
            }
        });

The call to remove the listener is there to prevent repeated invocations of your custom handler on layout changes... if you want to get those, you can omit it.

Solution 2 - Java

In short, the views are not built yet in onCreate(), onStart(), or onResume(). Since they technically don't exist (as far as the ViewGroup is concerned), their dimensions are 0.

In long, you can go here for a better explanation on how to handle it.

https://stackoverflow.com/questions/4142090/how-do-you-to-retrieve-dimensions-of-a-view-getheight-and-getwidth-always-r/4406090#4406090

Solution 3 - Java

Use this function to get Height or Width of View

private int getHeightOfView(View contentview) {
    contentview.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
    //contentview.getMeasuredWidth();
    return contentview.getMeasuredHeight();
}

Solution 4 - Java

I am answering this again to make sure people like me will understand how it works completely before implementing.

Q. Why do I get my view's height as 0?
A. Because the view's height that you are trying to get is not yet built in onCreate(), onStart(), or onResume().

Q. Now where and how am I supposed to get the view's height?
A. You can still get the view's params wherever you want it like, onCreate(), onStart(), or onResume(). Like below:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

       TextView tv = (TextView)findViewById(R.id.textview1);

       ViewTreeObserver viewTreeObserver = tv.getViewTreeObserver();
       if (viewTreeObserver.isAlive()) {
        viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                viewHeight = tv.getHeight();
               
            }
        });
      }
   }

However this time you will wait until you get the view's height before removing observer.

tv.getViewTreeObserver().removeOnGlobalLayoutListener(this);

Q. So what should I check before removing this listener?
**A.**Just put a if condition before removing treeObserver like,

 if (viewHeight != 0)                     
 tv.getViewTreeObserver().removeOnGlobalLayoutListener(this);

Final code:

ViewTreeObserver viewTreeObserver = tv.getViewTreeObserver();
        if (viewTreeObserver.isAlive()) {
            viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    int viewHeight = tv.getHeight();
                    if (viewHeight != 0)
                        tv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    
                }
            });
        }

Hope this explains why the getHeight returns 0 and how to get it properly. Thanks.

Solution 5 - Java

By getting your button in a View you can easily fetch its height etc. You can define an onClickListener like so:

Button b=(Button) findViewById(R.id.searchButton);
b.setOnClickListener(ButtonClick);
android.view.View.OnClickListener ButtonClick= new android.view.View.OnClickListener() {
	public void onClick(View v) { 
 v.getHeight();
}};

Hope this helps.

Solution 6 - Java

I've faced this problem, and given that nobody mentioned this solution, I feel it is useful to share.

You can @Override the onSizeChange method, which I guess happens at the inflation process.

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    getDimensions();
    
}

where getDimensions() is a method of your custom View, in which you call getHeight and getWidth and assign to your class fields and re-setup as needed.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlex BView Question on Stackoverflow
Solution 1 - JavaChrisView Answer on Stackoverflow
Solution 2 - JavaDeeVView Answer on Stackoverflow
Solution 3 - JavaAditya RohillaView Answer on Stackoverflow
Solution 4 - JavaVijay EView Answer on Stackoverflow
Solution 5 - JavaAbhilab DasView Answer on Stackoverflow
Solution 6 - JavaArthur TabbalView Answer on Stackoverflow