MGDroid
MGDroid

Reputation: 1659

get layout height and width at run time android

How can I get width and height of a linear layout which is defined in xml as fill_parent both in height and width? I have tried onmeasure method but I dont know why it is not giving exact value. I need these values in an Activity before oncreate method finishes.

Upvotes: 21

Views: 60421

Answers (5)

Andre Thiele
Andre Thiele

Reputation: 4241

A generic approach using Kotlin based on MGDroid's answer for API 16+.

/**
 * Align height of a container from wrap-content to actual height at runtime.
 * */
private fun <T: ViewGroup> alignContainerHeight(container: T) {
    container.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
        override fun onGlobalLayout() {

            // Obtain runtime height
            val availableHeight = container.measuredHeight

            if (availableHeight > 0) {
                container.viewTreeObserver.removeOnGlobalLayoutListener(this)
                setContainerHeight(container, availableHeight)
            }
        }
    })
}

/**
 * Note: Assumes that the parent is a LinearLayout.
 * */
private fun <T : ViewGroup> setContainerHeight(container: T, availableHeight: Int) {
    val availableWidth = container.measuredWidth
    val params = LinearLayout.LayoutParams(availableWidth, availableHeight)

    // Note: getLayoutParams() returns null if no parent exists
    if (container.layoutParams != null) {
        container.layoutParams = params
    }
}

Upvotes: 0

milka
milka

Reputation: 127

To get it work, you need to check whether the desired height value is bigger than 0 - and first then remove the onGlobalLayout listener and do whatever you want with the height. The listener calls its method continuously and by the first call it is not guaranteed that the view is measured properly.

    final LinearLayout parent = (LinearLayout) findViewById(R.id.parentView);
    parent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            int availableHeight = parent.getMeasuredHeight();
            if(availableHeight>0) {
                parent.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                //save height here and do whatever you want with it
            }
        }
    });

Upvotes: 5

Eftekhari
Eftekhari

Reputation: 1021

You could add on layout change listener to your layout and get the newest height and width or even the one before last change.

Added in API level 11

Add a listener that will be called when the bounds of the view change due to layout processing.

LinearLayout myLinearLayout = (LinearLayout) findViewById(R.id.my_linear_layout);
myLinearLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            // Preventing extra work because method will be called many times.
            if(height == (bottom - top))
                return;
            
            height = (bottom - top);
            // do something here...
           }
     });

Upvotes: 3

MGDroid
MGDroid

Reputation: 1659

Suppose I have to get a LinearLayout width defined in XML. I have to get reference of it by XML. Define LinearLayout l as instance.

 l = (LinearLayout)findviewbyid(R.id.l1);
ViewTreeObserver observer = l.getViewTreeObserver();
        observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @Override
            public void onGlobalLayout() {
                // TODO Auto-generated method stub
                init();
            l.getViewTreeObserver().removeGlobalOnLayoutListener(
                    this);
        }
    });

protected void init() {
        int a= l.getHeight();
            int b = l.getWidth();
Toast.makeText(getActivity,""+a+" "+b,3000).show();
    } 
    callfragment();
}  

Upvotes: 38

tom502
tom502

Reputation: 701

The width and height values are set after the layout has been created, when elements have been placed they then get measured. On the first call to onSizeChanged the parms will be 0 so if you use that check for it.

Little more detail here https://groups.google.com/forum/?fromgroups=#!topic/android-developers/nNEp6xBnPiw

and here http://developer.android.com/reference/android/view/View.html#Layout

Here is how to use onLayout:

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int width = someView.getWidth();
    int height = someView.getHeight();
}

Upvotes: 5

Related Questions