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

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
        }
    });
}

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.


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.