View's getWidth() and getHeight() returning 0
Asked Answered
C

8

23

I have looked at the similar questions and tried their solutions, but it didn't work for me. I'm trying to read width of an imageView, but it is returning 0. Here is the code:

public class MainActivity extends Activity {
private ImageView image1;   
float centerX,centerY;
private ImageView image2;
private boolean isFirstImage = true;

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.rotate);
    image1 = (ImageView) findViewById(R.id.ImageView01);
    image2 = (ImageView) findViewById(R.id.ImageView02);
    image2.setVisibility(View.GONE);

    if (isFirstImage) {
        applyRotation(0, 90);
        isFirstImage = !isFirstImage;
    }   
}   

private void applyRotation(float start, float end) {

    centerX=image1.getWidth()/2.0f;
    centerY=image1.getHeight()/2.0f;
    final Flip3dAnimation rotation =

    new Flip3dAnimation(start, end,centerX , centerY);
    rotation.setDuration(500);
    rotation.setFillAfter(true);
    rotation.setInterpolator(new AccelerateInterpolator());
    rotation.setAnimationListener(new DisplayNextView(isFirstImage, image1,
            image2));

    if (isFirstImage)
    {
        image1.startAnimation(rotation);
    } else {
        image2.startAnimation(rotation);
    }
}
}

Can anyone help me with this? Thanks

Complexioned answered 16/8, 2013 at 8:22 Comment(1)
There are more than enough questions/answers on SO covering this topic. In a nutshell you are accessing the width and height when the are not measured yet.Alcohol
S
22

You need to use the onSizechanged() method.

This is called during layout when the size of this view has changed

Shiff answered 16/8, 2013 at 11:23 Comment(2)
But How he use onSizechanged() method. this method is protected method and he can ovrride this method only if he create it`s own layout extends from ViewTrimorphism
That is true. Why I answered this way I cannot remember but if accessing the width and height of the ImageView from the Activity of Fragment then it should be done somewhere later in the lifecyle such as in the onStart() although I couldn't find an explicit statement where the height and width become non-zero.Fredette
F
19

You should use: image1.getLayoutParams().width;

Felix answered 30/9, 2014 at 0:22 Comment(1)
this returns -1 for me in onStart methodSurely
M
11

You are either accessing the ImageViews width and height before it has been measured, or after you set its visibility to GONE.

image2.setVisibility(View.GONE);

Then getWidth() or getHeight() will return 0.,

You can also have a look at onWindowFocusChanged(), onSizeChanged() and onMeasure():

 @Override
 public void onWindowFocusChanged(boolean focus) {
    super.onWindowFocusChanged(focus);
    // get the imageviews width and height here
 }
Maricela answered 16/8, 2013 at 8:30 Comment(0)
C
5
public class GETImageView extends ImageView {

public GETImageView (Context context, AttributeSet attrs) {
    super(context, attrs);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    Drawable d = getDrawable();

    if (d != null) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}

The ImageView have not yet draw the image, so no width or height return. You may use a subclass to get the imageview width.

Here is some link provide you another easy methods:

How to get the width and height of an android.widget.ImageView?

How to get the width and height of an Image View in android?

Android ImageView return getWidth, getHeight zero

Hope this help you.

Cancroid answered 16/8, 2013 at 8:32 Comment(2)
I don't know how to thank you. Part of your above code helped me a lot. int width = MeasureSpec.getSize(widthMeasureSpec);. I had spent almost 2 days and tried all permutations and combinations to get my work done, but this line helped me figure out the solution. :)Steep
We are just helping each other to save time~ Never mind~Cancroid
T
2

you can use OnGlobalLayoutListener for the ImageView image1 so you can get exact width and height occupied by the view in the layout...as

image1 = (ImageView) findViewById(R.id.ImageView01);
        ViewTreeObserver viewTreeObserver = image1.getViewTreeObserver();
        viewTreeObserver
                .addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        if (isFirstImage) {
                            applyRotation(0, 90);
                            isFirstImage = !isFirstImage;
                        } 
                        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN)
                            image1.getViewTreeObserver()
                                    .removeOnGlobalLayoutListener(this);
                        else
                            image1.getViewTreeObserver()
                                    .removeGlobalOnLayoutListener(this);
                    }
                });
Tonyatonye answered 7/4, 2014 at 5:22 Comment(1)
This is not the case when the visibility is gone. I mean, you can not get the width or height like that in that case.Eubanks
A
1

By the way, views don't get sized until the measurement steps have been taken. See this link:

getWidth() and getHeight() of View returns 0

Atiptoe answered 14/3, 2014 at 0:22 Comment(0)
D
0

Maybe you should call View.measure(int,int) first.
Since the width and height is not defined until this view is draw. You can call measure by hand to enforce this view to calculate it's size;

Dibrin answered 18/11, 2014 at 8:47 Comment(0)
R
-9

Please using a Handler and get height and width on this with delay time >= 10

This may be useful for use:

@Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        getHeight();

    }

    private void getHeight() {
        // TODO Auto-generated method stub
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(), "Height:" + mAnimationView.getMeasuredHeight(),
                        Toast.LENGTH_SHORT).show();
            }
        }, 10L);

    }
Regionalism answered 9/5, 2014 at 9:53 Comment(1)
It's really not a good idea to do it this way. You have no guarantee that an arbitrary delay of 10 is going to be long enough for layout to have happened.Swingletree

© 2022 - 2024 — McMap. All rights reserved.