getWidth() and getHeight() always returning 0. Custom view

前端 未结 7 2007
悲哀的现实
悲哀的现实 2020-12-09 09:11

In a Fragment, I am inflating a Layout with multiple child View. I need to get the dimensions (width and height) of one of them which is a custom view.

Inside the

相关标签:
7条回答
  • 2020-12-09 09:27

    Using ViewTreeObserver.OnGlobalLayoutListener, View.post(Runnable action) or onWindowFocusChanged() isn't the best solution. This article (note: I am the author of this article) explains why and provides a working solution using doOnLayout kotlin extension, which is based on View.OnLayoutChangeListener. If you want it in Java, in the article there's a link to doOnLayout source code, it's very simple and you can do something similar in Java too.

    0 讨论(0)
  • 2020-12-09 09:32

    Try checking in onWindowFocusChanged and it should have valid values:

    public void onWindowFocusChanged (boolean hasFocus) { }
    

    I had a similar issue where I needed to get width and height of a widget and this was the function in which I could guarantee the widget reported it's correct size.

    0 讨论(0)
  • 2020-12-09 09:34

    You must wait until after the first measure and layout in order to get nonzero values for getWidth() and getHeight(). You can do this with a ViewTreeObserver.OnGlobalLayouListener

    public void onViewCreated(final View view, Bundle saved) {
        super.onViewCreated(view, saved);
        view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                  view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                } else {
                  view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                }
    
                // get width and height of the view
            }
        });
    }
    
    0 讨论(0)
  • 2020-12-09 09:35

    You have to wait until the onSizeChanged() method is called before you can reliably determine the View size.

    This is called during layout when the size of this view has changed. If you were just added to the view hierarchy, you're called with the old values of 0.

    0 讨论(0)
  • 2020-12-09 09:35

    Try calling

    culoide.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);

    first, then try getWidth() and getHeight()

    0 讨论(0)
  • 2020-12-09 09:39

    My preferred method is to add an OnLayoutChangeListener to the view that you want to track itself

    CustomView customView = ...
    
    customView.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) {
            // Make changes
        }
    });
    

    You can remove the listener in the callback if you only want the initial layout.

    0 讨论(0)
提交回复
热议问题